重學(xué)多線程之sleep和wait的區(qū)別

一恕刘,sleep和wait方法的區(qū)別

1.從源碼來看

sleep 是Thread類的方法鹃锈,而且時(shí)一個(gè)native修飾的方法,是一個(gè)原生的方法

 /**
     * Causes the currently executing thread to sleep (temporarily cease
     * execution) for the specified number of milliseconds, subject to
     * the precision and accuracy of system timers and schedulers. The thread
     * does not lose ownership of any monitors.
     *
     * @param  millis
     *         the length of time to sleep in milliseconds
     *
     * @throws  IllegalArgumentException
     *          if the value of {@code millis} is negative
     *
     * @throws  InterruptedException
     *          if any thread has interrupted the current thread. The
     *          <i>interrupted status</i> of the current thread is
     *          cleared when this exception is thrown.
     */
    public static native void sleep(long millis) throws InterruptedException;

wait方法是Object類的方法

/**
     * 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()
     */
    public final void wait() throws InterruptedException {
        wait(0);
    }

2.調(diào)用方式的不同
  • sleep外部可以使。
  • wait只能夠在synchronized中使用(從上邊方法的描述中也可以看出他的使用方式,方法的掛起必須要有notify或者notifyAll來通知他去開始競(jìng)爭(zhēng)資源)
3.對(duì)資源的控制不同

sleep的時(shí)候是不會(huì)釋放鎖和cpu的,wait會(huì)釋放資源(cpu,鎖)

這也是下面例子中要著重說的

二媒佣,說明示例

代碼段1:驗(yàn)證wait()方法是會(huì)釋放鎖和cpu資源的

線程A中使用wait去進(jìn)行等待, 在啟動(dòng)完A時(shí),A線程掛起陵刹,等待通知去競(jìng)爭(zhēng)鎖默伍,主線程睡眠20毫秒,啟動(dòng)BBB線程,B線程睡20毫秒,之后通知A線程去競(jìng)爭(zhēng)鎖衰琐。

public static void main(String[] args) {
        //創(chuàng)建鎖對(duì)象
        final Object lock = new Object();
        // 線程AAA
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("thread AAA is waiting to get lock");
                synchronized (lock) {
                    System.out.println("thread AAA get lock ");
                    try {
                        System.out.println("thread AAA do wait method");
                        //Thread.sleep(10);
                        lock.wait();
                        System.out.println("thread AAA is done");

                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }).start();

        try {
            //主線程睡眠10毫秒等待讓兩個(gè)線程啟動(dòng)有個(gè)競(jìng)爭(zhēng)鎖的過程
            Thread.sleep(20);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        // 線程BBB
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("thread BBB is waiting to get lock");
                synchronized (lock) {
                    System.out.println("thread BBB get lock ");
                    try {
                       Thread.sleep(20);
                        System.out.println("thread BBB do wait method");
                        System.out.println("thread BBB is done");
                        lock.notifyAll();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }).start();
    }

執(zhí)行上邊代碼結(jié)果(多次執(zhí)行結(jié)果一致)

thread AAA is waiting to get lock
thread AAA get lock 
thread AAA do wait method
thread BBB is waiting to get lock
thread BBB get lock 
thread BBB do wait method
thread BBB is done
thread AAA is done

從打印的日志可以看出也糊,AAA 拿到lock鎖之后寨蹋,執(zhí)行wait方法被線程被掛起來了,然后BBB線程啟動(dòng)堵漱,但是BBB獲取到了Lock鎖嚎杨,進(jìn)行了下一步的執(zhí)行,并通知A線程去競(jìng)爭(zhēng)鎖和資源防泵,可以看出,AAA線程在wait方法掛起時(shí)是釋放了鎖和cpu等資源的,否則將會(huì)進(jìn)入無期限的等待當(dāng)中斗搞,不清楚的化可以對(duì)比執(zhí)行第二段代碼,只是將AAA中等待方法替換成了sleep等待方法

代碼的2

此段代碼中讓線程AAA睡眠40毫秒慷妙,讓線程BBB能夠在AAA線程的執(zhí)行過程中啟動(dòng)去競(jìng)爭(zhēng)鎖僻焚。

 public static void main(String[] args) {
        //創(chuàng)建鎖對(duì)象
        final Object lock = new Object();
        // 線程AAA
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("thread AAA is waiting to get lock");
                synchronized (lock) {
                    System.out.println("thread AAA get lock ");
                    try {

                        System.out.println("thread AAA do wait method");
                        Thread.sleep(40);
                       // Thread.sleep(20);
                        System.out.println("thread AAA is done");

                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }).start();

        try {
            //主線程睡眠10毫秒等待讓兩個(gè)線程啟動(dòng)有個(gè)競(jìng)爭(zhēng)鎖的過程
            Thread.sleep(20);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        // 線程BBB
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("thread BBB is waiting to get lock");
                synchronized (lock) {
                    System.out.println("thread BBB get lock ");
                    try {
                       Thread.sleep(20);
                        System.out.println("thread BBB do wait method");
                        System.out.println("thread BBB is done");
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }).start();
    }

多次執(zhí)行結(jié)果如下

thread AAA is waiting to get lock
thread AAA get lock 
thread AAA do wait method
thread BBB is waiting to get lock
thread AAA is done
thread BBB get lock 
thread BBB do wait method
thread BBB is done

從執(zhí)行結(jié)果可以看到膝擂,BBB的線程雖然是在AAA線程的執(zhí)行過程中啟動(dòng)了虑啤,但是一直沒有獲取到lock鎖,一直在等待架馋,當(dāng)AAA線程執(zhí)行完之后狞山,BBB才獲取到鎖,所以線程使用再使用sleep方法睡眠時(shí)并沒有釋放鎖和cpu資源叉寂。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末萍启,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子屏鳍,更是在濱河造成了極大的恐慌勘纯,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,755評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件钓瞭,死亡現(xiàn)場(chǎng)離奇詭異驳遵,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)山涡,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門堤结,熙熙樓的掌柜王于貴愁眉苦臉地迎上來搏讶,“玉大人,你說我怎么就攤上這事霍殴∶教瑁” “怎么了?”我有些...
    開封第一講書人閱讀 165,138評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵来庭,是天一觀的道長(zhǎng)妒蔚。 經(jīng)常有香客問我,道長(zhǎng)月弛,這世上最難降的妖魔是什么肴盏? 我笑而不...
    開封第一講書人閱讀 58,791評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮帽衙,結(jié)果婚禮上菜皂,老公的妹妹穿的比我還像新娘。我一直安慰自己厉萝,他們只是感情好恍飘,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,794評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著谴垫,像睡著了一般章母。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上翩剪,一...
    開封第一講書人閱讀 51,631評(píng)論 1 305
  • 那天乳怎,我揣著相機(jī)與錄音,去河邊找鬼前弯。 笑死蚪缀,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的恕出。 我是一名探鬼主播询枚,決...
    沈念sama閱讀 40,362評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼剃根!你這毒婦竟也來了哩盲?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,264評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤狈醉,失蹤者是張志新(化名)和其女友劉穎廉油,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體苗傅,經(jīng)...
    沈念sama閱讀 45,724評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡抒线,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了渣慕。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片嘶炭。...
    茶點(diǎn)故事閱讀 40,040評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡抱慌,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出眨猎,到底是詐尸還是另有隱情抑进,我是刑警寧澤,帶...
    沈念sama閱讀 35,742評(píng)論 5 346
  • 正文 年R本政府宣布睡陪,位于F島的核電站寺渗,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏兰迫。R本人自食惡果不足惜信殊,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,364評(píng)論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望汁果。 院中可真熱鬧涡拘,春花似錦、人聲如沸据德。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽晋控。三九已至汞窗,卻和暖如春姓赤,著一層夾襖步出監(jiān)牢的瞬間赡译,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評(píng)論 1 270
  • 我被黑心中介騙來泰國打工不铆, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留蝌焚,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,247評(píng)論 3 371
  • 正文 我出身青樓誓斥,卻偏偏與公主長(zhǎng)得像只洒,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子劳坑,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,979評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容