信號

當使用文件系統時需要限制線程數時,通常會使用信號量。通過計數器控制對文件或其他共享資源的訪問。如果其值大於零,則允許訪問,但同時計數器會減少。

在計數器歸零的那一刻,當前線程將被阻塞,直到資源被另一個線程釋放。必須通過構造函數設置權限參數的數量。

您需要單獨選擇此參數,具體取決於您的計算機或筆記本電腦的功率。

public class Main {

   public static void main(String[] args) {
       Semaphore sem = new Semaphore(1);
       CommonResource res = new CommonResource();
       new Thread(new MyThread(res, sem, "MyThread_1")).start();
       new Thread(new MyThread(res, sem, "MyThread_2")).start();
       new Thread(new MyThread(res, sem, "MyThread_3")).start();
   }
}

class CommonResource {
   int value = 0;
}

class MyThread implements Runnable {
   CommonResource commonResource;
   Semaphore semaphore;
   String name;
   MyThread(CommonResource commonResource, Semaphore sem, String name) {
       this.commonResource = commonResource;
       this.semaphore = sem;
       this.name = name;
   }

   public void run() {

       try {
           System.out.println(name + "waiting permission");
           semaphore.acquire();
           commonResource.value = 1;
           for (int i = 1; i < 7; i++) {
               System.out.println(this.name + ": " + commonResource.value);
               commonResource.value++;
               Thread.sleep(150);
           }
       } catch (InterruptedException e) {
           System.out.println(e.getMessage() + " " + name);
           Thread.currentThread().interrupt();
       }
       System.out.println(name + "releases permission");
       semaphore.release();
   }
}

CountDownLatch 等

CountDownLatch - 允許多個線程等待,直到對其他線程執行的一定數量的操作完成。一個例子是應用程序的安裝:直到您接受使用條款,它才會開始,直到您選擇一個文件夾來安裝新程序,等等。為此有一個特殊的countDown()方法- 此方法將倒計時計數器減一。

一旦計數歸零,await 中的所有等待線程將繼續其工作,並且所有後續的 await 調用將不等待而通過。遞減計數器是一次性計數器,不能重置。

CyclicBarrier - 用於在某一時刻同步給定數量的線程。當 N 個線程調用 await(...) 方法並阻塞時達到屏障。之後,計數器被重置為原來的值,等待的線程將被釋放。此外,如果需要,可以在取消阻塞線程和重置計數器之前運行自定義代碼。為此,通過構造函數傳遞一個實現了Runnable接口的對象。

Exchanger<V> Exchanger類用於線程之間的數據交換。它是類型化的,類型是線程需要交換的數據類型。

使用此類唯一的exchange()方法交換數據:

V exchange(V x) throws InterruptedException
V exchange(V x, long timeout, TimeUnit unit) throws InterruptedException, TimeoutException

x 參數表示要交換的數據緩衝區。該方法的第二種形式還定義了超時參數timeout 和unit,即用於超時參數的時間單位類型。

Phaser類允許您同步表示整體操作執行中的單個階段或階段的線程。Phaser定義了一個同步對象,它等待某個階段完成。Phaser然後進入下一階段或階段並等待它再次完成。

使用Phaser類時,通常首先創建其對象。接下來,我們需要註冊所有參與者。要為每個參與者註冊,調用register()方法,或者您可以通過將所需數量的參與者傳遞給Phaser構造函數來不使用此方法。

然後每個參與者執行一組特定的動作,這些動作構成了這個階段。Phaser同步器等待所有參與者完成階段的執行。要通知同步器該階段已結束,參與者必須調用arrive()arriveAndAwaitAdvance()方法。然後同步器進入下一階段。