Java 多線程基礎(七)線程休眠 sleep


Java 多線程基礎(七)線程休眠 sleep

一、線程休眠 sleep

sleep() 方法定義在Thread.java中,是 static 修飾的靜態方法。
sleep() 的作用是讓當前線程休眠,即當前線程會從“運行狀態”進入到“休眠(阻塞)狀態”。sleep()會指定休眠時間,線程休眠的時間會大於/等於該休眠時間;在線程重新被喚醒時,它會由“阻塞狀態”變成“就緒狀態”,從而等待cpu的調度執行。

二、sleep示例

public class SleepTest {
    private static Object obj = new Object();
    public static void main(String[] args) {
        Thread t1 = new MyThread("t1");
        t1.start();
    }
    
    static class MyThread extends Thread{
        public MyThread(String name) {
            super(name);
        }
        public void run() {
            synchronized (obj) {
                try {
                    for(int i = 0;i < 5;i++) {
                        System.out.println(Thread.currentThread().getName() + "--" + i);
                        if (i % 4 == 0)
                            Thread.sleep(1000);// i能被4整除時,休眠1秒
                    }
                }catch(Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
// 運行結果
t1--0  
t1--1
t1--2
t1--3
t1--4

說明:

在主線程main中啟動線程t1。t1啟動之后,當t1中的計算i能被4整除時,t1會通過Thread.sleep(100)休眠100毫秒。

三、sleep(long millis) 與 wait(long timeout)

我們知道,wait()的作用是讓當前線程由“運行狀態”進入“等待(阻塞)狀態”的同時,也會釋放同步鎖。而sleep()的作用是也是讓當前線程由“運行狀態”進入到“休眠(阻塞)狀態”。
但是,wait() 會釋放對象的同步鎖,而 sleep() 則不會釋放鎖

通過下面的代碼,演示 sleep() 不會釋放鎖的:

public class SleepTest {
    private static Object obj = new Object();
    public static void main(String[] args) {
        Thread t1 = new MyThread("t1");
        Thread t2 = new MyThread("t2");
        t1.start();
        t2.start();
    }
    
    static class MyThread extends Thread{
        public MyThread(String name) {
            super(name);
        }
        public void run() {
            synchronized (obj) {
                try {
                    for(int i = 0;i < 5;i++) {
                        System.out.println(Thread.currentThread().getName() + "--" + i);
               Thread.sleep(1000);// 休眠1秒 } }catch(Exception e) { e.printStackTrace(); } } } } }
// 執行結果
t1--0
t1--1
t1--2
t1--3
t1--4
t2--0
t2--1
t2--2
t2--3
t2--4

說明:

主線程main中啟動了兩個線程t1和t2。t1和t2在run()會引用同一個對象的同步鎖,即synchronized(obj)。在t1運行過程中,雖然它會調用Thread.sleep(1000) 進入休眠狀態;但是,t2是不會獲取CPU執行權的。因為,t1並沒有釋放“obj所持有的同步鎖”!
注意,若我們注釋掉 synchronized (obj) 后再次執行該程序,t1和t2是可以相互切換執行的,原因是:在沒有同步鎖的情況下,當一個線程進入“休眠(阻塞)狀態“時,會放棄CPU的執行權,另一個線程就會獲取CPU執行權。

通過下面的代碼,演示 wait() 會釋放鎖的:

public class SleepTest {
    private static Object obj = new Object();
    public static void main(String[] args) {
        Thread t1 = new MyThread("t1");
        Thread t2 = new MyThread("t2");
        t1.start();
        t2.start();
    }
    
    static class MyThread extends Thread{
        public MyThread(String name) {
            super(name);
        }
        public void run() {
            synchronized (obj) {
                try {
                    for(int i = 0;i < 5;i++) {
                        System.out.println(Thread.currentThread().getName() + "--" + i);
                        obj.wait(1000);// 等待1秒
                    }
                }catch(Exception e) {
                    e.printStackTrace();
                }
                
            }
        }
    }
}
// 執行結果
t1--0
t2--0
t1--1
t2--1
t2--2
t1--2
t2--3
t1--3
t2--4
t1--4

說明:

主線程main中啟動了兩個線程t1和t2。t1和t2在run()會引用同一個對象的同步鎖,即synchronized(obj)。在t1運行過程中,調用 obj.wait(1000) 進入等待狀態,釋放同步鎖;此時,t2會獲取CPU執行權的。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM