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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

Java线程阻塞原语-LockSupport

發布時間:2024/4/13 java 57 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java线程阻塞原语-LockSupport 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

在Java6引入LockSupport以前,線程掛起和喚醒要通過Object的wait和notify/notifyAllfangAll實現,但后者必須要在同步塊里調用,且notify必須要在wait之后調用才行否則會導致線程阻塞。

LockSupport比Object的wait/notify有兩大優勢:

  • LockSupport不需要在同步代碼塊里 。所以線程間也不需要維護一個共享的同步對象了,實現了線程間的解耦。
  • unpark函數可以先于park調用,所以不需要擔心線程間的執行的先后順序。
  • LockSupport原理

    LockSupport和每個使用它的線程都與一個許可(permit)關聯。permit類似信號量,相當于1,0的開關,默認是0(表示許可是被占用的,調用park()會阻塞),調用一次unpark被置為1,調用一次park會消費permit, 也就是將1變成0,同時park立即返回。再次調用park會變成block(因為permit為0了,會阻塞在這里,直到permit變為1), 這時調用unpark會把permit置為1。每個線程都有一個相關的permit, permit最多只有一個,重復調用unpark也不會積累

    park()和unpark()不會有 “Thread.suspend和Thread.resume所可能引發的死鎖” 問題,由于許可的存在,調用 park 的線程和另一個試圖將其 unpark 的線程之間的競爭將保持活性

    許可默認是占用的

    public static void main(String[] args)
    {
    ?? LockSupport.park();????? //此處阻塞,因為許可默認占用
    ?? System.out.println("block.");
    }

    ?

    public static void main(String[] args)
    {
    ?? Thread thread = Thread.currentThread();
    ?? LockSupport.unpark(thread);????????? //釋放許可
    ?? LockSupport.park();??????????????????????? // 獲取許可,此處不阻塞,繼續運行
    ?? System.out.println("b");
    }

    ?

    LockSupport不可重入

    public static void main(String[] args) throws Exception
    {
    ?Thread thread = Thread.currentThread();
    ?
    ?LockSupport.unpark(thread);? //釋放許可
    ?
    ?System.out.println("a");
    ?LockSupport.park();?????????????? // 獲取許可,此處不阻塞,繼續運行
    ?System.out.println("b");
    ?LockSupport.park();????????????? // 獲取不到許可,此處阻塞
    ?System.out.println("c");?
    }

    對中斷的響應

    線程如果因為調用park而阻塞的話,能夠響應中斷請求,park()方法返回不再阻塞,中斷狀態被設置成true,但是不會拋出InterruptedException。

    LockSupport函數列表

    // 返回提供給最近一次尚未解除阻塞的 park 方法調用的 blocker 對象,如果該調用不受阻塞,則返回 null。 static Object getBlocker(Thread t) // 為了線程調度,禁用當前線程,除非許可可用。 static void park() // 為了線程調度,在許可可用之前禁用當前線程 static void park(Object blocker) // 為了線程調度禁用當前線程,最多等待指定的等待時間,除非許可可用。 static void parkNanos(long nanos) // 為了線程調度,在許可可用前禁用當前線程,并最多等待指定的等待時間。 static void parkNanos(Object blocker, long nanos) // 為了線程調度,在指定的時限前禁用當前線程,除非許可可用。 static void parkUntil(long deadline) // 為了線程調度,在指定的時限前禁用當前線程,除非許可可用。 static void parkUntil(Object blocker, long deadline) // 如果給定線程的許可尚不可用,則使其可用。(釋放許可) static void unpark(Thread thread)

    blocker:這個對象是用來記錄線程被阻塞時被誰阻塞的。

    相對時間與絕對時間

    LockSupport的park()函數調用了unsafe.park()方法。

    public static void park() {unsafe.park(false, 0L);}public static void parkNanos(long nanos) {if (nanos > 0)unsafe.park(false, nanos);}public static void parkUntil(long deadline) {unsafe.park(true, deadline);} //Unsafe public native void park(boolean isAbsolute, long time);
    • nanos:在nanos時間后線程自動恢復掛起

    • deadline:在deadline時刻線程自動(這個毫秒其實就是自1970年1月1日0時起的毫秒數)

    park方法是一個阻塞的方法,除非4個條件

  • 當配對的unpark發生

  • 線程被中斷時恢復

  • 阻塞時間已過

    • 當absolute是false時,如果給定的時間是非0(負數)或者給定的時間(正數, 時間單位時毫秒)已經過去了(0的時候會一直阻塞著)。
    • 當Absolute是true時,如果給定的時間(時間單位是納秒)過去了或者偽造的(在我理解是參數不合法時)線程會恢復中斷。

    ?

    ?

    ?

    ?

    ?

    ?

    總結

    以上是生活随笔為你收集整理的Java线程阻塞原语-LockSupport的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。