Java 多執行緒基礎(七)執行緒休眠 sleep
- 2020 年 6 月 18 日
- 筆記
- Java 多執行緒基礎
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執行權的。