背景
sleep作用:等待當(dāng)前線程n秒后,繼續(xù)執(zhí)行。
問題
- 等待過程中,是否交出CPU?如果交出了,如何保證下一次能繼續(xù)調(diào)用到?引申出另外一個同步問題,sleep是阻斷的還是非阻斷的?為什么?
- sleep的用途都是在哪里?原理是什么?
- 跟其他阻斷線程的都有哪些?都有什么比較
Sleep底層實現(xiàn)
sleep是jvm基于操作系統(tǒng)底層的實現(xiàn)而封裝實現(xiàn)的。
Sleep大致原理
- 掛起進(jìn)程(或線程)并修改其運行狀態(tài),即讓出CPU控制權(quán)限;
- 用sleep()提供的參數(shù)來設(shè)置一個定時器;
- 當(dāng)時間結(jié)束,定時器會觸發(fā),內(nèi)核收到中斷后修改進(jìn)程(或線程)的運行狀態(tài)。例如線程會被標(biāo)志為就緒而進(jìn)入就緒隊列等待調(diào)度。
常用Sleep方法的調(diào)用:
try {
Thread.sleep(1000); // sleep 1秒
} catch (InterruptedException e) {
e.printStackTrace();
}
ps:這里的catch說明一下,一般當(dāng)前線程的狀態(tài),可以被其它線程使用interrupt調(diào)用從而暫停該線程。所以一般需要正常的catch。
public class PrimeProducer extends Thread {
private final BlockingQueue<BigInteger> queue;
PrimeProducer(BlockingQueue<BigInteger> queue) {
this.queue = queue;
}
public void run() {
try {
BigInteger p = BigInteger.ONE;
while (!Thread.currentThread().isInterrupted())
queue.put(p = p.nextProbablePrime());
} catch (InterruptedException consumed) {
/* Allow thread to exit */
}
}
public void cancel() { interrupt(); }
}
linux的sleep方法參考:
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
///時鐘編程 alarm()
void wakeUp()
{
printf("please wakeup!!/n");
}
int main(void)
{
printf("you have 4 s sleep!/n");
signal(SIGALRM,wakeUp);
alarm(4);
//將進(jìn)程掛起
pause();
printf("good morning!/n");
return EXIT_SUCCESS;
}
問題解答
- 會交出CPU控制權(quán)限。待到達(dá)時間后,進(jìn)入了就緒隊列,不能保證立馬就執(zhí)行到。再者,是同步代碼塊,并未釋放同步鎖,阻斷其它線程的調(diào)用。
- sleep交出當(dāng)前線程的CPU控制權(quán)限,讓其它同優(yōu)先等級的線程有機(jī)會使用。原理是操作系統(tǒng)支持。大致步驟如上。
- 跟其它的比較最多的就是屬于Object的方法wait
3.1 屬于不同的兩個類,sleep()方法是線程類(Thread)的靜態(tài)方法,wait()方法是Object類里的方法;
3.2 sleep()方法不會釋放鎖,wait()方法釋放對象鎖;
3.3 sleep()方法可以在任何地方使用,wait()方法則只能在同步方法或同步塊中使用;
3.4 sleep()必須捕獲異常,wait()方法、notify()方法和notiftAll()方法不需要捕獲異常;
3.5 sleep()使線程進(jìn)入阻塞狀態(tài)(線程睡眠),wait()方法使線程進(jìn)入等待隊列(線程掛起),也就是阻塞類別不同;