線程同步之wait/notify

一直對線程同步的wait/notify不太理解借杰, 今天有空demo實踐了下

public class Test {
    private static final Object lock = new Object();

    public static void main(String[] args) {
        testWaitAndNotify();
    }

    private static void testWaitAndNotify() {
        Thread thread1 = new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (lock) {
                    while (true) {
                        System.out.println("thread1 的run 方法-準備睡兩秒->" + System.currentTimeMillis());
                        try {
                            Thread.sleep(2000);
                            System.out.println("thread1 -醒了釋放鎖了-自己wait->" + System.currentTimeMillis());(1)
                            lock.notify();
                            System.out.println("thread1 -我在睡3秒后才會釋放鎖->" + System.currentTimeMillis());
                            Thread.sleep(3000);
                            lock.wait();(1)
                            System.out.println("thread1 被叫醒了-->" + System.currentTimeMillis());
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        });
        thread1.start();
        Thread thread2 = new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (lock) {
                    while (true) {
                        System.out.println("thread2 的run 方法-->準備睡兩秒->" + System.currentTimeMillis());
                        try {
                            Thread.sleep(2000);
//                            lock.wait();
                            System.out.println("thread2醒了釋放鎖了-自己wait-->" + System.currentTimeMillis());
                            lock.notify();
                            System.out.println("thread2 -我在睡3秒后才會釋放鎖->" + System.currentTimeMillis());
                            Thread.sleep(3000);
                            lock.wait();(2)
                            System.out.println("thread2 被叫醒了-->" + System.currentTimeMillis());
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        });
        thread2.start();

    }
}
image.png

可以看到,thread1先拿到鎖并得到執(zhí)行进泼,然后在(1)處執(zhí)行wait讓出鎖蔗衡,然后,thread2拿到鎖乳绕,并得到執(zhí)行绞惦,并在(2)處執(zhí)行wait釋放鎖,然后需要注意的是洋措,本線程是在notify所在代碼塊執(zhí)行完畢后济蝉,才有機會競爭該把鎖

 /**
     * Causes the current thread to wait until another thread invokes the
     * {@link java.lang.Object#notify()} method or the
     * {@link java.lang.Object#notifyAll()} method for this object.
     * In other words, this method behaves exactly as if it simply
     * performs the call {@code wait(0)}.
     * <p>
     * The current thread must own this object's monitor. The thread
     * releases ownership of this monitor and waits until another thread
     * notifies threads waiting on this object's monitor to wake up
     * either through a call to the {@code notify} method or the
     * {@code notifyAll} method. The thread then waits until it can
     * re-obtain ownership of the monitor and resumes execution.
     * <p>
     * As in the one argument version, interrupts and spurious wakeups are
     * possible, and this method should always be used in a loop:
     * <pre>
     *     synchronized (obj) {
     *         while (&lt;condition does not hold&gt;)
     *             obj.wait();
     *         ... // Perform action appropriate to condition
     *     }
     * </pre>
     * This method should only be called by a thread that is the owner
     * of this object's monitor. See the {@code notify} method for a
     * description of the ways in which a thread can become the owner of
     * a monitor.
     *
     * @throws  IllegalMonitorStateException  if the current thread is not
     *               the owner of the object's monitor.
     * @throws  InterruptedException if any thread interrupted the
     *             current thread before or while the current thread
     *             was waiting for a notification.  The <i>interrupted
     *             status</i> of the current thread is cleared when
     *             this exception is thrown.
     * @see        java.lang.Object#notify()
     * @see        java.lang.Object#notifyAll()
     */
    @FastNative
    public final native void wait() throws InterruptedException;

 /**
     * Wakes up a single thread that is waiting on this object's
     * monitor. If any threads are waiting on this object, one of them
     * is chosen to be awakened. The choice is arbitrary and occurs at
     * the discretion of the implementation. A thread waits on an object's
     * monitor by calling one of the {@code wait} methods.
     * <p>
     * The awakened thread will not be able to proceed until the current
     * thread relinquishes the lock on this object. The awakened thread will
     * compete in the usual manner with any other threads that might be
     * actively competing to synchronize on this object; for example, the
     * awakened thread enjoys no reliable privilege or disadvantage in being
     * the next thread to lock this object.
     * <p>
     * This method should only be called by a thread that is the owner
     * of this object's monitor. A thread becomes the owner of the
     * object's monitor in one of three ways:
     * <ul>
     * <li>By executing a synchronized instance method of that object.
     * <li>By executing the body of a {@code synchronized} statement
     *     that synchronizes on the object.
     * <li>For objects of type {@code Class,} by executing a
     *     synchronized static method of that class.
     * </ul>
     * <p>
     * Only one thread at a time can own an object's monitor.
     *
     * @throws  IllegalMonitorStateException  if the current thread is not
     *               the owner of this object's monitor.
     * @see        java.lang.Object#notifyAll()
     * @see        java.lang.Object#wait()
     */
    @FastNative
    public final native void notify();

    /**
     * Wakes up all threads that are waiting on this object's monitor. A
     * thread waits on an object's monitor by calling one of the
     * {@code wait} methods.
     * <p>
     * The awakened threads will not be able to proceed until the current
     * thread relinquishes the lock on this object. The awakened threads
     * will compete in the usual manner with any other threads that might
     * be actively competing to synchronize on this object; for example,
     * the awakened threads enjoy no reliable privilege or disadvantage in
     * being the next thread to lock this object.
     * <p>
     * This method should only be called by a thread that is the owner
     * of this object's monitor. See the {@code notify} method for a
     * description of the ways in which a thread can become the owner of
     * a monitor.
     *
     * @throws  IllegalMonitorStateException  if the current thread is not
     *               the owner of this object's monitor.
     * @see        java.lang.Object#notify()
     * @see        java.lang.Object#wait()
     */
    @FastNative
    public final native void notifyAll();

(1).wait(),notify(),notifyAll()都是本地方法,并且為final方法呻纹,無法被重寫
(2).wait(),notify(),notifyAll()堆生,是object的方法专缠,不是Thread的方法
(3).調(diào)用某個對象的wait()的方法能讓當前線程阻塞雷酪,并且,當前線程必須擁有此對象的monitor
(4).調(diào)用某個對象的notify()方法能夠喚醒一個正在等待這個對象monitor的線程囤官,度過由多個線程在等待這個monitor循集,則只能喚醒其中一個(按等待順序)
(5).調(diào)用notifyAll()能狗煥醒所有正在等待這個對象的monitor的線程

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末迎卤,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子吩跋,更是在濱河造成了極大的恐慌,老刑警劉巖渔工,帶你破解...
    沈念sama閱讀 206,482評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件锌钮,死亡現(xiàn)場離奇詭異,居然都是意外死亡引矩,警方通過查閱死者的電腦和手機梁丘,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,377評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來旺韭,“玉大人氛谜,你說我怎么就攤上這事∏耍” “怎么了值漫?”我有些...
    開封第一講書人閱讀 152,762評論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長织盼。 經(jīng)常有香客問我杨何,道長酱塔,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,273評論 1 279
  • 正文 為了忘掉前任危虱,我火速辦了婚禮延旧,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘槽地。我一直安慰自己迁沫,他們只是感情好,可當我...
    茶點故事閱讀 64,289評論 5 373
  • 文/花漫 我一把揭開白布捌蚊。 她就那樣靜靜地躺著集畅,像睡著了一般。 火紅的嫁衣襯著肌膚如雪缅糟。 梳的紋絲不亂的頭發(fā)上挺智,一...
    開封第一講書人閱讀 49,046評論 1 285
  • 那天,我揣著相機與錄音窗宦,去河邊找鬼赦颇。 笑死,一個胖子當著我的面吹牛赴涵,可吹牛的內(nèi)容都是我干的媒怯。 我是一名探鬼主播,決...
    沈念sama閱讀 38,351評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼髓窜,長吁一口氣:“原來是場噩夢啊……” “哼扇苞!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起寄纵,我...
    開封第一講書人閱讀 36,988評論 0 259
  • 序言:老撾萬榮一對情侶失蹤鳖敷,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后程拭,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體定踱,經(jīng)...
    沈念sama閱讀 43,476評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,948評論 2 324
  • 正文 我和宋清朗相戀三年恃鞋,在試婚紗的時候發(fā)現(xiàn)自己被綠了崖媚。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,064評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡山宾,死狀恐怖至扰,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情资锰,我是刑警寧澤敢课,帶...
    沈念sama閱讀 33,712評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響直秆,放射性物質(zhì)發(fā)生泄漏濒募。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,261評論 3 307
  • 文/蒙蒙 一圾结、第九天 我趴在偏房一處隱蔽的房頂上張望瑰剃。 院中可真熱鬧,春花似錦筝野、人聲如沸晌姚。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,264評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽挥唠。三九已至,卻和暖如春焕议,著一層夾襖步出監(jiān)牢的瞬間宝磨,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,486評論 1 262
  • 我被黑心中介騙來泰國打工盅安, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留唤锉,地道東北人。 一個月前我還...
    沈念sama閱讀 45,511評論 2 354
  • 正文 我出身青樓别瞭,卻偏偏與公主長得像窿祥,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子畜隶,可洞房花燭夜當晚...
    茶點故事閱讀 42,802評論 2 345