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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

由Thread.sleep引发的

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

首先,對比下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


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


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

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


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

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

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

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

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

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


下面寫個程序查看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.*");}} }
運行程序

top 找到進程的pid =?10149

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

top -H -p 10149

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

查看jvm中這些線程的詳細信息

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

就可以看到十進制的線程號


通過這個線程號查看?top -H -p 10149中顯示的cpu占用率和mem占用率即可


也可以用 ?printf "%x" 10183 活動線程的十六進制線程號,查看在jstack中的信息。


通過上述操作可以看到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引发的的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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