溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

java代碼實(shí)現(xiàn)線程通信

發(fā)布時(shí)間:2020-06-02 10:16:20 來(lái)源:億速云 閱讀:127 作者:Leah 欄目:編程語(yǔ)言

本篇文章展示了java代碼實(shí)現(xiàn)線程通信的具體操作,代碼簡(jiǎn)明扼要容易理解,如果在日常工作遇到這個(gè)疑問。希望大家通過(guò)這篇文章,找到解決疑問的辦法。

使用兩個(gè)線程打印1-100,交替打印
涉及到的方法:
wait()--一旦執(zhí)行此方法,當(dāng)前線程就進(jìn)入阻塞狀態(tài),并釋放同步監(jiān)視器
notify()--一旦執(zhí)行此方法,就會(huì)喚醒wait的一個(gè)線程,如果有多個(gè)線程wait,就喚醒優(yōu)先級(jí)高的
notifyAll()---一旦執(zhí)行此方法,會(huì)喚醒所有被wait的線程

說(shuō)明:
(1)實(shí)現(xiàn)線程通信wait()\notify()\notifyAll()三個(gè)方法必須使用在同步代碼塊或同步方法中
(2)上述三個(gè)代碼的調(diào)用者必須是同步代碼塊或同步方法中的同步監(jiān)視器
否則會(huì)出現(xiàn)異常java.lang.IllegalMonitorStateException
(3)wait()\notify()\notifyAll()在java.lang.Object類中
sleep()和wait()方法的異同
(1)相同點(diǎn):一旦執(zhí)行方法,都可以使當(dāng)前線程進(jìn)入阻塞狀態(tài)
(2)不同點(diǎn):
a)兩個(gè)方法聲明的位置不同:Thread類中聲明sleep(),Object類中聲明wait()
b)調(diào)用的要求不一樣,sleep()可以在任何需要的場(chǎng)景調(diào)用,
wait()必須使用在同步代碼塊或同步方法中
c)關(guān)于是否釋放同步監(jiān)視器:如果兩個(gè)方法都使用在同步代碼塊或同步方法中:
sleep()--不會(huì)釋放鎖,wait()會(huì)釋放鎖
d)sleep()時(shí)間到了,線程就被喚醒
wait()需要使用notify/notifyAll()來(lái)喚醒

    public class CommunicationTest {
       public static void main(String[] args) {
        Number number=new Number();
        Thread t1 = new Thread(number);
        Thread t2 = new Thread(number);
        t1.setName("線程1");
        t2.setName("線程2");
        t1.start();
        t2.start();
    }

        class Number implements Runnable{
    private int number=1;
    private Object obj=new Object();
    @Override
    public void run() {
        while(true){
           // synchronized (this) {
              synchronized (obj) {//調(diào)用notify的對(duì)象和同步監(jiān)視器obj不是同一個(gè)對(duì)象,會(huì)出現(xiàn)異常
                                  //加上obj.wait(),obj.notify()就對(duì)了
                obj.notify();
                if(number<=100){
                    System.out.println(Thread.currentThread().getName()+":"+number);
                    number++;

                    try {
                        //使得調(diào)用如下wait()方法的線程進(jìn)入阻塞狀態(tài)
                        obj.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }else{
                    break;
                }
            }
        }
    }
    }

釋放鎖的操作:
(1)當(dāng)前線程的同步方法、同步代碼塊執(zhí)行結(jié)束
(2)當(dāng)前線程在同步代碼塊、同步方法中遇到break\return終止了該代碼塊,該方法繼續(xù)執(zhí)行
(3)當(dāng)前線程在同步代碼塊、同步方法中出現(xiàn)了未處理的Error/Exception,導(dǎo)致異常結(jié)束
(4)當(dāng)前線程在同步代碼塊、同步方法中執(zhí)行類線程對(duì)象的wait()方法,當(dāng)前線程暫停,并釋放鎖

不會(huì)釋放鎖的操作:
(1)線程執(zhí)行同步代碼塊、同步方法時(shí),調(diào)用Thread.sleep()\Thread.yield()方法暫停當(dāng)前線程的執(zhí)行
(2)線程執(zhí)行同步代碼塊時(shí),其他線程調(diào)用了該線程的suspend()方法將該線程掛起,該線程不會(huì)釋放鎖(同步監(jiān)          視器)--盡量避免使用suspend、resume控制線程

以上就是java代碼實(shí)現(xiàn)線程通信的詳細(xì)內(nèi)容了,看完之后是否有所收獲呢?如果想了解更多相關(guān)內(nèi)容,歡迎關(guān)注億速云行業(yè)資訊!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI