セマフォ

セマフォは通常、ファイル システムを操作するときにスレッド数を制限する必要がある場合に使用されます。ファイルまたはその他の共有リソースへのアクセスは、カウンターを通じて制御されます。その値がゼロより大きい場合、アクセスは許可されますが、同時にカウンターは減少します。

カウンタがゼロを返した時点で、現在のスレッドは別のスレッドによってリソースが解放されるまでブロックされます。アクセス許可パラメータの数は、コンストラクターを介して設定する必要があります。

コンピュータまたはラップトップの能力に応じて、このパラメータを個別に選択する必要があります。

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 - 他のスレッドで実行された一定数の操作が完了するまで、複数のスレッドが待機できるようにします。例としては、アプリケーションのインストールがあります。アプリケーションは、使用条件に同意するか、新しいプログラムをインストールするフォルダーを選択するまで、開始されません。これには特別なcountDown()メソッドがあり、このメソッドはカウント ダウン カウンターを 1 つデクリメントします。

カウントが 0 になるとすぐに、await 内の待機中のすべてのスレッドは作業を続行し、後続の await の呼び出しはすべて待機せずに渡されます。カウント ダウン カウンタは 1 回限りのカウンタであり、リセットできません。

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 パラメータは、交換されるデータ バッファを表します。このメソッドの 2 番目の形式では、タイムアウトパラメータ、タイムアウト、およびタイムアウトパラメータに使用する時間単位のタイプであるユニットも定義します。

Phaserクラスを使用すると、アクション全体の実行における単一のフェーズまたはステージを表すスレッドを同期できます。Phaser は、特定のフェーズが完了するまで待機する同期オブジェクトを定義します。その後、フェイザーは次のステージまたはフェーズに進み、再び完了するのを待ちます。

Phaserクラスを使用する場合、最初にそのオブジェクトを作成するのが一般的です。次に、参加者全員を登録する必要があります。各参加者を登録するには、register()メソッドを呼び出します。または、このメソッドを使用せずに、必要な参加者の数をPhaserコンストラクターに渡すことによって行うこともできます。

次に、各参加者はフェーズを構成する特定の一連のアクションを実行します。そして、フェイザーシンクロナイザーは、すべての参加者がフェーズの実行を完了するまで待機します。フェーズが終了したことをシンクロナイザーに通知するには、参加者は、arrivy()メソッドまたはdeliveryAndAwaitAdvance()メソッドを呼び出す必要があります。その後、シンクロナイザーは次のフェーズに進みます。