日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

由Thread.sleep引发的

發(fā)布時(shí)間:2024/9/30 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 由Thread.sleep引发的 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

首先,對(duì)比下sleep和wait的區(qū)別

sleep()?is a method which is used to hold the process for few seconds or the time you wanted but in case of?wait()?method thread goes in waiting state and it won’t come back automatically until we call the notify() or notifyAll().

The?major difference?is that wait() releases the lock or monitor while sleep() doesn’t releases any lock or monitor while waiting. Wait is used for inter-thread communication while sleep is used to introduce pause on execution, generally.

Thread.sleep() sends the current thread into the “Not Runnable” state for some amount of time. The thread keeps the monitors it has acquired — i.e. if the thread is currently in a synchronized block or method no other thread can enter this block or method. If another thread calls t.interrupt() it will wake up the sleeping thread. Note that sleep is a static method, which means that it always affects the current thread (the one that is executing the sleep method). A common mistake is to call t.sleep() where t is a different thread; even then, it is the current thread that will sleep, not the t thread.

object.wait() sends the current thread into the “Not Runnable” state, like sleep(), but with a twist. Wait is called on an object, not a thread; we call this object the “l(fā)ock object.” Before lock.wait() is called, the current thread must synchronize on the lock object; wait() then releases this lock, and adds the thread to the “wait list” associated with the lock. Later, another thread can synchronize on the same lock object and call lock.notify(). This wakes up the original, waiting thread. Basically, wait()/notify() is like sleep()/interrupt(), only the active thread does not need a direct pointer to the sleeping thread, but only to the shared lock object.

synchronized(LOCK) {???Thread.sleep(1000); // LOCK is held }synchronized(LOCK) {???LOCK.wait(); // LOCK is not held }

Let categorize all above points :

Call on:

  • ?? ?wait(): Call on an object; current thread must synchronize on the lock object.
  • ?? ?sleep(): Call on a Thread; always currently executing thread.

Synchronized:

  • ?? ?wait(): when synchronized multiple threads access same Object one by one.
  • ?? ?sleep(): when synchronized multiple threads wait for sleep over of sleeping thread.

Hold lock:

  • ?? ?wait(): release the lock for other objects to have chance to execute.
  • ?? ?sleep(): keep lock for at least t times if timeout specified or somebody interrupt.

Wake-up condition:

  • ?? ?wait(): until call notify(), notifyAll() from object
  • ?? ?sleep(): until at least time expire or call interrupt().

Usage:

  • ?? ?sleep(): for time-synchronization and;
  • ?? ?wait(): for multi-thread-synchronization.

之前一直有誤解就是,sleep肯定是占用cpu的,而wait不占用cpu,這就是為什么大家經(jīng)常推薦wait


后來(lái)查到的資料,和自己寫(xiě)程序驗(yàn)證,sleep期間也是不占用cpu的,首先要先了解java線程的狀態(tài)


新建狀態(tài):用new語(yǔ)句創(chuàng)建的線程對(duì)象處于新建狀態(tài),此時(shí)它和其它的java對(duì)象一樣,僅僅在堆中被分配了內(nèi)存?
就緒狀態(tài):當(dāng)一個(gè)線程創(chuàng)建了以后,其他的線程調(diào)用了它的start()方法,該線程就進(jìn)入了就緒狀態(tài)。處于這個(gè)狀態(tài)的線程位于可運(yùn)行池中,等待獲得CPU的使用權(quán)?
運(yùn)行狀態(tài):處于這個(gè)狀態(tài)的線程占用CPU,執(zhí)行程序的代碼?
阻塞狀態(tài):當(dāng)線程處于阻塞狀態(tài)時(shí),java虛擬機(jī)不會(huì)給線程分配CPU,直到線程重新進(jìn)入就緒狀態(tài),它才有機(jī)會(huì)轉(zhuǎn)到運(yùn)行狀態(tài)。?
阻塞狀態(tài)分為三種情況:?
1、 位于對(duì)象等待池中的阻塞狀態(tài):當(dāng)線程運(yùn)行時(shí),如果執(zhí)行了某個(gè)對(duì)象的wait()方法,java虛擬機(jī)就回把線程放到這個(gè)對(duì)象的等待池中?
2、 位于對(duì)象鎖中的阻塞狀態(tài),當(dāng)線程處于運(yùn)行狀態(tài)時(shí),試圖獲得某個(gè)對(duì)象的同步鎖時(shí),如果該對(duì)象的同步鎖已經(jīng)被其他的線程占用,JVM就會(huì)把這個(gè)線程放到這個(gè)對(duì)象的瑣池中。?
3、 其它的阻塞狀態(tài):當(dāng)前線程執(zhí)行了sleep()方法,或者調(diào)用了其它線程的join()方法,或者發(fā)出了I/O請(qǐng)求時(shí),就會(huì)進(jìn)入這個(gè)狀態(tài)中。?

死亡狀態(tài):當(dāng)線程退出了run()方法,就進(jìn)入了死亡狀態(tài),該線程結(jié)束了生命周期。?
?????????? 或者正常退出?
?????????? 或者遇到異常退出?
?????????? Thread類(lèi)的isAlive()方法判斷一個(gè)線程是否活著,當(dāng)線程處于死亡狀態(tài)或者新建狀態(tài)時(shí),該方法返回false,在其余的狀態(tài)下,該方法返回true.?


線程調(diào)度?
線程調(diào)度模型:分時(shí)調(diào)度模型和搶占式調(diào)度模型?
JVM采用搶占式調(diào)度模型。?
所謂的多線程的并發(fā)運(yùn)行,其實(shí)是指宏觀上看,各個(gè)線程輪流獲得CPU的使用權(quán),分別執(zhí)行各自的任務(wù)。?
(線程的調(diào)度不是跨平臺(tái),它不僅取決于java虛擬機(jī),它還依賴(lài)于操作系統(tǒng))?

如果希望明確地讓一個(gè)線程給另外一個(gè)線程運(yùn)行的機(jī)會(huì),可以采取以下的辦法之一?
1、 調(diào)整各個(gè)線程的優(yōu)先級(jí)?
2、 讓處于運(yùn)行狀態(tài)的線程調(diào)用Thread.sleep()方法?
3、 讓處于運(yùn)行狀態(tài)的線程調(diào)用Thread.yield()方法?
4、 讓處于運(yùn)行狀態(tài)的線程調(diào)用另一個(gè)線程的join()方法?

調(diào)整各個(gè)線程的優(yōu)先級(jí)?
Thread類(lèi)的setPriority(int)和getPriority()方法分別用來(lái)設(shè)置優(yōu)先級(jí)和讀取優(yōu)先級(jí)。?
如果希望程序能夠移值到各個(gè)操作系統(tǒng)中,應(yīng)該確保在設(shè)置線程的優(yōu)先級(jí)時(shí),只使用MAX_PRIORITY、NORM_PRIORITY、MIN_PRIORITY這3個(gè)優(yōu)先級(jí)。?

線程睡眠:當(dāng)線程在運(yùn)行中執(zhí)行了sleep()方法時(shí),它就會(huì)放棄CPU,轉(zhuǎn)到阻塞狀態(tài)。?
線程讓步:當(dāng)線程在運(yùn)行中執(zhí)行了Thread類(lèi)的yield()靜態(tài)方法時(shí),如果此時(shí)具有相同優(yōu)先級(jí)的其它線程處于就緒狀態(tài),那么yield()方法將把當(dāng)前運(yùn)行的線程放到運(yùn)行池中并使另一個(gè)線程運(yùn)行。如果沒(méi)有相同優(yōu)先級(jí)的可運(yùn)行線程,則yield()方法什么也不做。?
Sleep()方法和yield()方法都是Thread類(lèi)的靜態(tài)方法,都會(huì)使當(dāng)前處于運(yùn)行狀態(tài)的線程放棄CPU,把運(yùn)行機(jī)會(huì)讓給別的線程,兩者的區(qū)別在于:?
???????? 1、sleep()方法會(huì)給其他線程運(yùn)行的機(jī)會(huì),而不考慮其他線程的優(yōu)先級(jí),因此會(huì)給較低線程一個(gè)運(yùn)行的機(jī)會(huì);yield()方法只會(huì)給相同優(yōu)先級(jí)或者更高優(yōu)先級(jí)的線程一個(gè)運(yùn)行的機(jī)會(huì)。?
2、當(dāng)線程執(zhí)行了sleep(long millis)方法后,將轉(zhuǎn)到阻塞狀態(tài),參數(shù)millis指定睡眠時(shí)間;當(dāng)線程執(zhí)行了yield()方法后,將轉(zhuǎn)到就緒狀態(tài)。?
????????? 3、sleep()方法聲明拋出InterruptedException異常,而yield()方法沒(méi)有聲明拋出任何異常?
????????? 4、sleep()方法比yield()方法具有更好的移植性?

等待其它線程的結(jié)束:join()?
????????? 當(dāng)前運(yùn)行的線程可以調(diào)用另一個(gè)線程的 join()方法,當(dāng)前運(yùn)行的線程將轉(zhuǎn)到阻塞狀態(tài),直到另一個(gè)線程運(yùn)行結(jié)束,它才恢復(fù)運(yùn)行。?

定時(shí)器Timer:在JDK的java.util包中提供了一個(gè)實(shí)用類(lèi)Timer, 它能夠定時(shí)執(zhí)行特定的任務(wù)。?


下面寫(xiě)個(gè)程序查看sleep線程的cpu占用率

public class Main {public static void main(String[] args) {new Thread(new Idle(), "Idle").start();new Thread(new Busy(), "Busy").start();} }class Idle implements Runnable {@Overridepublic void run() {try {TimeUnit.HOURS.sleep(1);} catch (InterruptedException e) {}} }class Busy implements Runnable {@Overridepublic void run() {while(true) {"Foo".matches("F.*");}} }
運(yùn)行程序

top 找到進(jìn)程的pid =?10149

查看進(jìn)程下的所有線程(-H是顯示線程)

top -H -p 10149

這是會(huì)顯示十幾個(gè)線程,其中有兩個(gè)是我們的工作線程,busy和Idle,剩下的大部分是gc線程

查看jvm中這些線程的詳細(xì)信息

jstack?10149


看到其中有兩條信息

"Busy" prio=10 tid=0x00007f2a700d0800 nid=0x27c7 runnable [0x00007f29f5c68000]

"Idle" prio=10 tid=0x00007f2a700ce800 nid=0x27c6 waiting on condition [0x00007f29f5d69000]


printf "%d"?0x27c7

就可以看到十進(jìn)制的線程號(hào)


通過(guò)這個(gè)線程號(hào)查看?top -H -p 10149中顯示的cpu占用率和mem占用率即可


也可以用 ?printf "%x" 10183 活動(dòng)線程的十六進(jìn)制線程號(hào),查看在jstack中的信息。


通過(guò)上述操作可以看到Idle的線程cpu的占用率為0




參考:http://howtodoinjava.com/2013/03/08/difference-between-sleep-and-wait/

http://blog.csdn.net/android_tutor/article/details/5293974

總結(jié)

以上是生活随笔為你收集整理的由Thread.sleep引发的的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。