多執行緒三 執行緒中常用的函式

2021-07-22 12:13:55 字數 2814 閱讀 1953

1.  sleep()

1.1   執行緒睡眠:thread.sleep(long millis)方法,使執行緒轉到阻塞狀態。millis引數設定睡眠的時間,以毫秒為單位。當睡眠結束後,就轉為就緒(runnable)狀態。當前執行緒(即呼叫該方法的執行緒)暫停執行一段時間,讓其他執行緒有機會繼續執行,但它並不釋放物件鎖。也就是說如果有synchronized同步快,其他執行緒仍然不能訪問共享資料。注意該方法要捕捉異常。

例如  有兩個執行緒同時執行(沒有synchronized)乙個執行緒優先順序為max_priority,另乙個為min_priority,如果沒有sleep()方法,只有高優先順序的執行緒執行完畢後,低優先順序的執行緒才能夠執行;但是高優先順序的執行緒sleep(500)後,低優先順序就有機會執行了。

特殊例子 sleep(0) 作用就是讓低優先順序的執行緒有機會執行。

總之,sleep()可以使低優先順序的執行緒得到執行的機會,當然也可以讓同優先順序、高優先順序的執行緒有執行的機會。

1.2   在jdk 1.5之後,使用 timeunit.milliseconds.sleep(100); 代替sleep(100).

需要注意,使用sleep(100)並不能保證100毫秒後此執行緒立刻執行,具體在cpu分配

2.  wait(),notify(),notifyall()

2.1  執行緒等待:object類中的wait()方法,導致當前的執行緒等待,直到其他執行緒呼叫此物件的 notify() 方法或 notifyall() 喚醒方法。這兩個喚醒方法也是object類中的方法,行為等價於呼叫 wait(0) 一樣。

這三個方法用於協調多個執行緒對共享資料的訪問,所以必須在同步語句塊內使用。synchronized關鍵字用於保護共享資料,阻止其他執行緒對共享資料的訪問,但是這樣程式的流程就很不靈活了,如何才能在當前執行緒還沒退出synchronized資料塊時讓其他執行緒也有機會訪問共享資料呢?此時就用這三個方法來靈活控制。

wait()方法使當前執行緒暫停執行並釋放物件鎖,讓其他執行緒可以進入synchronized資料塊,當前執行緒被放入物件等待池中。當呼叫notify()方法後,將從物件的等待池中移走乙個任意的執行緒並放到鎖標誌等待池中,只有鎖標誌等待池中線程能夠獲取鎖標誌;如果鎖標誌等待池中沒有執行緒,則notify()不起作用。

notifyall()則從物件等待池中移走所有等待那個物件的執行緒並放到鎖標誌等待池中。

乙個經典的例子說明wait(),notify()的使用:

開啟至少三個執行緒,迴圈列印abc十次:下面是我自己寫的實現,可能有瑕疵。

public class waitthread implements runnable else catch (interruptedexception e) }}

synchronized (this) else catch (interruptedexception e) }}

synchronized (this) else catch (interruptedexception e) }}

}}public static void main(string args) }

3. sleep() 和wait() 的區別。

3.1 sleep()用於執行緒控制,而wait()用於執行緒間的通訊,由於wait函式的特殊意義,所以他是應該放在同步語句塊中的,這樣才有意義.

3.2   sleep(10) 在設定的毫秒數之後可能被喚醒《注意不是一定》,而wait()使當前執行緒阻塞,但是此執行緒麼有結束,一直被監聽,直到 出現 notify() , notifyall()時候,此執行緒繼續執行。也可以指定時間,自動喚醒。

4. yield()

4.1  執行緒讓步:thread.yield() 方法,暫停當前正在執行的執行緒物件,把執行機會讓給相同或者更高優先順序的執行緒。注意:這裡的其他也包含當前執行緒。該方法與sleep()類似,只是不能由使用者指定暫停多長時間。

實際上,yield()方法對應了如下操作;先檢測當前是否有相同優先順序的執行緒處於可執行狀態,如有,則把cpu的佔有權交給此執行緒,否則繼續執行原來的執行緒,所以yield()方法稱為「退讓」,它把執行機會讓給了同等級的其他執行緒。

5. sleep()和yield()區別

sleep 方法允許較低優先順序的執行緒獲得執行機會,但yield()方法執行時,當前執行緒仍處在可執行狀態,所以不可能讓出較低優先順序的執行緒此時獲取cpu佔有權。在乙個執行系統中,如果較高優先順序的執行緒沒有呼叫sleep方法,也沒有受到i/o阻塞,那麼較低優先順序執行緒只能等待所有較高優先順序的執行緒執行結束,方可有機會執行。

6. join()

join()方法,等待其他執行緒終止。在當前執行緒中呼叫另乙個執行緒的join()方法,則當前執行緒轉入阻塞狀態,直到另乙個執行緒執行結束,當前執行緒再由阻塞轉為就緒狀態。

在很多情況下,主線程生成並起動了子執行緒,如果子執行緒裡要進行大量的耗時的運算,主線程往往將於子執行緒之前結束,但是如果主線程處理完其他的事務後,需要用到子執行緒的處理結果,也就是主線程需要等待子執行緒執行完成之後再結束,這個時候就要用到join()方法了。

public class jointest implements runnable  

}  public static void main(string args) throws exception          }

如上,如果我們注釋掉t.join();執行緒大部分時候可能不會輸出5,因為當主線程 main方法執行system.out.println(a);這條語句時,執行緒還沒有真正開始執行,或許正在為它分配資源準備執行。因為為執行緒分配資源需要時間,而main方法執行完t.start()方法後繼續往下執行system.out.println(a);,這個時候得到的結果是a還沒有被 改變的值0 。怎樣才能讓輸出結果為5!其實很簡單,join() 方法提供了這種功能。join() 方法,它能夠使呼叫該方法的執行緒在此之前執行完畢。

多執行緒系列三 執行緒常用方法

獲取當前執行緒 currentthread 該方法返回執行currentthread 這個方法當前執行緒的資訊 返回的是thread例項 使用這個方法可以獲取執行緒的名稱等 下面來看一下比較複雜的例子 public class threadmethodtest override public voi...

多執行緒學習(三) 執行緒的屬性

屬性名稱 用途注意事項 id每個執行緒都有自己的id,用於識別不同的執行緒 被後續建立的執行緒使用 不允許被修改 name 便於使用者在開發 除錯或執行過程中區分每個不同的執行緒 定位問題等 清晰有意義的名字 預設的名稱 isdaemon true 代表是守護執行緒,false 非守護執行緒 使用者...

Linux多執行緒學習(三)執行緒屬性

執行緒的建立函式pthread creat的第二個引數為pthread attr t型別的指標 預設屬性建立執行緒時賦值null pthread attr t是乙個結構體型別,定義如下 typedef struct pthread attr t 執行緒屬性的使用步驟 建立屬性物件 以預設值初始化屬性...