線程中sleep()和wait()的差別

基本的差別

  • sleepThread類的方法,waitObject類中定義的方法
  • sleep()方法可以在任何地方使用
  • wait()方法只能在synchronized方法或者synchronized塊中使用

本質區別

  • Thread.sleep()只會讓出CPU資源,不會導致鎖行爲的改變
  • Object.wait()不僅讓出CPU資源,還會釋放已經佔有的同步鎖

我們來看下面兩個例子

package com.mtli.thread;

/**
 * @Description:
 * @Author: Mt.Li
 * @Create: 2020-05-05 07:56
 */
public class WaitSleepDemo {
    public static void main(String[] args) {
        final Object lock = new Object();
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("線程A正在等待獲取同步鎖");
                try {
                    synchronized (lock) {
                        System.out.println("線程A已經獲取到鎖");
                        Thread.sleep(20);
                        System.out.println("線程A執行wait方法");
                        lock.wait(1000);
                        System.out.println("線程A執行完畢");
                    }
                }catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();
        try {
            Thread.sleep(10);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("線程B正在等待獲取同步鎖");
                try {
                    synchronized (lock) {
                        System.out.println("線程B已經獲取到鎖");
                        Thread.sleep(10);
                        System.out.println("線程B執行sleep方法");
                        Thread.sleep(1000);
                        System.out.println("線程B執行完畢");
                    }
                }catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }

}

// 執行結果:

線程A正在等待獲取同步鎖
線程A已經獲取到鎖
線程B正在等待獲取同步鎖
線程A執行wait方法
線程B已經獲取到鎖
線程B執行sleep方法
線程B執行完畢
線程A執行完畢

從結果我們可以分析,線程A執行wait()方法之前,線程B只是啓動運行並在鎖池中進行等待,線程A執行wait()方法之後,線程B需要獲取鎖才能執行的部分被執行了,說明這個時候,線程B獲取到了lock對象鎖,也就驗證了wait不僅僅釋放CPU資源,還會釋放同步鎖,這時候該線程就會進入當前對象的等待池中,等待時間結束,或者被主動喚醒。

對代碼稍加修改:

package com.mtli.thread;

/**
 * @Description:
 * @Author: Mt.Li
 * @Create: 2020-05-05 07:56
 */
public class WaitSleepDemo {
    public static void main(String[] args) {
        final Object lock = new Object();
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("線程A正在等待獲取同步鎖");
                try {
                    synchronized (lock) {
                        System.out.println("線程A已經獲取到鎖");
                        Thread.sleep(20);
                        System.out.println("線程A執行sleep方法");
                        Thread.sleep(1000);
                        System.out.println("線程A執行完畢");
                    }
                }catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();
        try {
            Thread.sleep(10);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("線程B正在等待獲取同步鎖");
                try {
                    synchronized (lock) {
                        System.out.println("線程B已經獲取到鎖");
                        Thread.sleep(10);
                        System.out.println("線程B執行sleep方法");
                        Thread.sleep(1000);
                        System.out.println("線程B執行完畢");
                    }
                }catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }

}

// 結果:

線程A正在等待獲取同步鎖
線程A已經獲取到鎖
線程B正在等待獲取同步鎖
線程A執行sleep方法
線程A執行完畢
線程B已經獲取到鎖
線程B執行sleep方法
線程B執行完畢

從結果可以顯而易見,sleep方法並不會釋放鎖,但是會釋放CPU資源(出讓CPU時間片,畢竟Java線程是搶佔式的)

以上均爲個人理解,若有錯誤,請各位看官及時提出(輕噴),如有爭議,大家可以一起交流

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章