成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

Java多線程中wait 和 notify 方法理解

Turbo / 3166人閱讀

摘要:必須放在中,否則會(huì)在時(shí)扔出異常。為了控制線程執(zhí)行的順序,那么就必須要確定喚醒等待的順序,所以每一個(gè)線程必須同時(shí)持有兩個(gè)對(duì)象鎖,才能繼續(xù)執(zhí)行。一個(gè)對(duì)象鎖是,就是前一個(gè)線程所持有的對(duì)象鎖。

簡(jiǎn)單介紹

wait()方法是Object類里的方法;當(dāng)一個(gè)線程執(zhí)行到wait()方法時(shí),它就進(jìn)入到一個(gè)和該對(duì)象相關(guān)的等待池中,同時(shí)失去(釋放)了對(duì)象的機(jī)鎖(暫時(shí)失去機(jī)鎖,wait(long timeout)超時(shí)時(shí)間到后還需要返還對(duì)象鎖);其他線程可以訪問(wèn);wait()使用notify或者notifyAlll或者指定睡眠時(shí)間來(lái)喚醒當(dāng)前等待池中的線程。wiat()必須放在synchronized block中,否則會(huì)在program runtime時(shí)扔 出“java.lang.IllegalMonitorStateException”異常。
簡(jiǎn)單的介紹就到這里,現(xiàn)在我們用一個(gè)例子來(lái)深入理解一下
package com.example.demo.test.MultithreadingTest;

public class MyThreadPrinter2 implements Runnable {
    private String name;
    private Object prev;
    private Object self;

    private MyThreadPrinter2(String name, Object prev, Object self) {
        this.name = name;
        this.prev = prev;
        this.self = self;
    }

    @Override
    public void run() {
        int count = 10;
        int x=0;
        while (count > 0) {
            synchronized (prev) {
                synchronized (self) {
                    System.out.print(name);
                    count--;
                    x++;
                    self.notify();
                }
                try {
                    prev.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            synchronized (prev){
                System.out.print(x);
            }

        }
    }

    public static void main(String[] args) throws Exception {
        Object a = new Object();
        Object b = new Object();
        Object c = new Object();
        MyThreadPrinter2 pa = new MyThreadPrinter2("A", c, a);
        MyThreadPrinter2 pb = new MyThreadPrinter2("B", a, b);
        MyThreadPrinter2 pc = new MyThreadPrinter2("C", b, c);

        new Thread(pa).start();
        Thread.sleep(100);
        new Thread(pb).start();
        Thread.sleep(100);
        new Thread(pc).start();
        Thread.sleep(100);
    }
}

輸出結(jié)果:
ABC1A1B1C2A2B2C3A3B3C4A4B4C5A5B5C6A6B6C7A7B7C8A8B8C9A9B9C10

這段代碼為三線程間的同步喚醒操作,主要的目的就是ThreadA->ThreadB->ThreadC->ThreadA循環(huán)執(zhí)行三個(gè)線程。
為了控制線程執(zhí)行的順序,那么就必須要確定喚醒、等待的順序,所以每一個(gè)線程必須同時(shí)持有兩個(gè)對(duì)象鎖,才能繼續(xù)執(zhí)行。一個(gè)對(duì)象鎖是prev,就是前一個(gè)線程所持有的對(duì)象鎖。還有一個(gè)就是自身對(duì)象鎖。主要的思想就是,為了控制執(zhí)行的順序,必須要先持有prev鎖,也就前一個(gè)線程要釋放自身對(duì)象鎖,再去申請(qǐng)自身對(duì)象鎖,兩者兼?zhèn)鋾r(shí)打印,之后首先調(diào)用self.notify()釋放自身對(duì)象鎖,喚醒下一個(gè)等待線程,再調(diào)用prev.wait()釋放prev對(duì)象鎖,終止當(dāng)前線程,等待循環(huán)結(jié)束后再次被喚醒。prev.wait()之后,加入了一個(gè)對(duì)象鎖是prev的輸出x,用來(lái)展示什么時(shí)候釋放了prev對(duì)象鎖。
運(yùn)行上述代碼,可以發(fā)現(xiàn)先打印出A,再釋放A,然后C鎖,進(jìn)入ThreadB,打印出B,再釋放B,然后A鎖,進(jìn)入ThreadC,打印出C,再釋放C,然后B鎖,此時(shí)會(huì)進(jìn)入ThreadA,繼續(xù)執(zhí)行開始時(shí)wait的線程,輸出x,打印出A,再釋放A,然后C鎖......如此循環(huán)

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/71618.html

相關(guān)文章

  • Java 線程編程之:notify wait 用法

    摘要:和簡(jiǎn)介和均為的方法暫停一個(gè)線程喚醒一個(gè)線程從以上的定義中,我們可以了解到以下事實(shí)想要使用這兩個(gè)方法,我們需要先有一個(gè)對(duì)象。在中任何一個(gè)時(shí)刻,對(duì)象的控制權(quán)只能被一個(gè)線程擁有。若有多個(gè)線程處于此控制權(quán)下的狀態(tài),只有一個(gè)會(huì)被喚醒。 最近看帖子,發(fā)現(xiàn)一道面試題: 啟動(dòng)兩個(gè)線程, 一個(gè)輸出 1,3,5,7…99, 另一個(gè)輸出 2,4,6,8…100 最后 STDOUT 中按序輸出 1,2,3,4...

    eccozhou 評(píng)論0 收藏0
  • Object對(duì)象你真理解了嗎?

    摘要:無(wú)論在中出現(xiàn)什么,都可以認(rèn)為它是對(duì)象除了八大基本數(shù)據(jù)類型。讓當(dāng)前線程等待某個(gè)對(duì)象的鎖,當(dāng)然應(yīng)該通過(guò)這個(gè)對(duì)象來(lái)操作了。但是要注意的是方法調(diào)用后,被喚醒的線程不會(huì)立馬獲得到鎖對(duì)象。主要的區(qū)別在于在釋放同時(shí),釋放了對(duì)象鎖的控制。 前言 五一回家又?jǐn)喔艘粋€(gè)放假時(shí)間了~~~ 只有光頭才能變強(qiáng) 回顧前面: ThreadLocal就是這么簡(jiǎn)單 多線程三分鐘就可以入個(gè)門了! 多線程基礎(chǔ)必要知識(shí)點(diǎn)!...

    anquan 評(píng)論0 收藏0
  • Java 并發(fā)學(xué)習(xí)筆記

    摘要:方法可以將當(dāng)前線程放入等待集合中,并釋放當(dāng)前線程持有的鎖。此后,該線程不會(huì)接收到的調(diào)度,并進(jìn)入休眠狀態(tài)。該線程會(huì)喚醒,并嘗試恢復(fù)之前的狀態(tài)。 并發(fā) 最近重新復(fù)習(xí)了一邊并發(fā)的知識(shí),發(fā)現(xiàn)自己之前對(duì)于并發(fā)的了解只是皮毛。這里總結(jié)以下Java并發(fā)需要掌握的點(diǎn)。 使用并發(fā)的一個(gè)重要原因是提高執(zhí)行效率。由于I/O等情況阻塞,單個(gè)任務(wù)并不能充分利用CPU時(shí)間。所以在單處理器的機(jī)器上也應(yīng)該使用并發(fā)。為...

    DrizzleX 評(píng)論0 收藏0
  • Java線程學(xué)習(xí)(四)等待/通知(wait/notify)機(jī)制

    摘要:運(yùn)行可運(yùn)行狀態(tài)的線程獲得了時(shí)間片,執(zhí)行程序代碼。阻塞的情況分三種一等待阻塞運(yùn)行的線程執(zhí)行方法,會(huì)把該線程放入等待隊(duì)列中。死亡線程方法執(zhí)行結(jié)束,或者因異常退出了方法,則該線程結(jié)束生命周期。死亡的線程不可再次復(fù)生。 系列文章傳送門: Java多線程學(xué)習(xí)(一)Java多線程入門 Java多線程學(xué)習(xí)(二)synchronized關(guān)鍵字(1) java多線程學(xué)習(xí)(二)synchronized關(guān)鍵...

    PiscesYE 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<