天天看點

java 線程休眠 30秒_Java 多線程基礎(七)線程休眠 sleep

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

一、線程休眠 sleep

sleep() 方法定義在Thread.java中,是 static 修飾的靜态方法。

sleep() 的作用是讓目前線程休眠,即目前線程會從“運作狀态”進入到“休眠(阻塞)狀态”。sleep()會指定休眠時間,線程休眠的時間會大于/等于該休眠時間;線上程重新被喚醒時,它會由“阻塞狀态”變成“就緒狀态”,進而等待cpu的排程執行。

二、sleep示例

public classSleepTest {private static Object obj = newObject();public static voidmain(String[] args) {

Thread t1= new MyThread("t1");t1.start();

}static class MyThread extendsThread{publicMyThread(String name) {super(name);

}public voidrun() {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--0t1--1t1--2t1--3t1--4

說明:

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

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

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

但是,wait() 會釋放對象的同步鎖,而 sleep() 則不會釋放鎖。

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

public classSleepTest {private static Object obj = newObject();public static voidmain(String[] args) {

Thread t1= new MyThread("t1");

Thread t2= new MyThread("t2");

t1.start();

t2.start();

}static class MyThread extendsThread{publicMyThread(String name) {super(name);

}public voidrun() {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--0t1--1t1--2t1--3t1--4t2--0t2--1t2--2t2--3t2--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 classSleepTest {private static Object obj = newObject();public static voidmain(String[] args) {

Thread t1= new MyThread("t1");

Thread t2= new MyThread("t2");

t1.start();

t2.start();

}static class MyThread extendsThread{publicMyThread(String name) {super(name);

}public voidrun() {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--0t2--0t1--1t2--1t2--2t1--2t2--3t1--3t2--4t1--4

說明:

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