Javaでは、スレッドの同期にセマフォを使用します。 これは、カウンタ変数を使用する共有リソースへのアクセスを制御するために使用されます。 Javaにはセマフォクラスがあり、共有資源に対するアクセスを制御するためのコンストラクタや様々なメソッドが用意されています。

この節を進める前に、まず、セマフォとは何か、セマフォの種類、仕組み、セマフォの実装方法について理解します。

セマフォとは何か

セマフォは、共有資源にアクセスしたいスレッドの数を制限するために使用されます。 つまり、カウンタと呼ばれるスレッド間で共有される非負の変数です。 スレッドの上限を設定するものです。 あるスレッドがセマフォで待機している仕組みは、他のスレッドからシグナルを受けることができる。

  • Counter > 0なら共有リソースへのアクセスを提供する。
  • カウンター = 0なら共有リソースへのアクセスを拒否する。

要するに、カウンターが共有リソースに与えた許可回数を追跡し続けているのである。 したがって、セマフォはスレッドにリソースを共有する許可を与える。

Characteristics of Semaphore

セマフォには以下の特徴がある:

  • It provides synchronization among the threads.
  • It decreases the level of synchronization.これは、スレッド間の同期を行う。 したがって、低レベルの同期メカニズムを提供する。
  • セマフォは負の値を含んでいない。
  • セマフォは負の値を持たない。0より大きいか0に等しい値を持つ。
  • テスト操作と割り込みを使ってセマフォを実装し、実行にはファイルディスクリプタを使う。

Semaphore

セマフォはカウンター変数を通して共有資源を制御する。 カウンタは非負の値である。

  • カウンタ>が0の場合、スレッドは共有リソースにアクセスする許可を得て、カウンタ値は1だけ減少する。
  • さもなければ、許可を得ることができるまでスレッドがブロックされる。
  • 他のスレッドが資源の取得を待っている場合、そのスレッドはその時点で許可を取得します。
  • counter = 0の場合、スレッドは共有資源へのアクセス許可を取得しません。

フローチャートを使ってセマフォの働きを理解しましょう。

Javaセマフォ

セマフォの種類

セマフォには次の4種類がある。

  • カウントセマフォ
  • 境界セマフォ
  • タイミングセマフォ
  • バイナリセマフォ

Java Semaphore

一つずつ詳しく説明しましょう。

カウントセマフォ

カウントセマフォは、クリティカルセクションで複数のプロセスが同時に実行しようとする状況を解決するために使用されます。 したがって、この問題を克服するために、カウントセマフォを使用する。

CountingSemaphoresExample.java

境界セマフォ

境界セマフォを使用して上限を設定することができます。 計数セマフォには上限値が含まれていないため、計数セマフォの代わりに使用される。 上限値は、それが格納できるシグナルの数を示す。

BoundedSemaphoresExample.java

時限セマフォ

時限セマフォは、スレッドを一定時間だけ実行させることができます。

時限セマフォの実装を見てみましょう。

TimedSemaphoresExample.java

Binary Semaphores

2進セマフォはカウントセマフォと同じものです。 しかし、0か1の2進数の値しか受け付けないことを覚えておいてください。 他のセマフォと比較して実装は簡単である。

BinarySemaphoresExample.java

Semaphore in Java

Javaでは、スレッド同期構造の1つである。 この構成では、共有リソースへのアクセスを制御するカウンタと呼ばれる変数を使用します。 これは変数の一種で、同時実行プロセスを管理し、またそれらを同期させるために使用される。 また、競合状態を回避するためにも使用されます。

たとえば、あるファイルに同時にアクセスできるスレッド数を10に制限することができます。

Java Semaphore Class

Javaはセマフォ機構を実装するためにSemaphoreクラスを提供しています。 これはjava.util.concurrentパッケージに属します。 Serializableインタフェースを実装しています。

セマフォクラスは以下の2つのコンストラクタを提供します:

  • Semaphore(int permits)
  • Semaphore(int permits, boolean fair)

Semaphore(int permits)

Semaphoreを生成して引数に許可件数(許可できる初期数)をパーズしています。 これは一度にリソースを共有できるスレッドの数を指定する。 permitsの値は負になることもある。

Syntax:

Semaphore(int permits, boolean fair)

これは、与えられた許可数と与えられた公平性の設定を持つセマフォを作成します。 permitsの値は負である可能性があります。 この場合、acquireが許可される前にreleaseが発生しなければなりません。

  • fair: この値をtrueにすると、セマフォは要求された順番にスレッドにFIFOを保証します。 false デフォルトでは、リソースを待っているすべてのスレッドが不定の順番で許可を与えます。
  • Semaphoreクラスのメソッド

    このクラスには次のメソッドがあります。 このメソッドはセマフォから許可証を取得し、1つが利用可能になるまでブロックするか、スレッドが割り込まれる。

    現在のスレッドで利用可能な許可証がない場合、スレッドはスレッドスケジューリングのために無効になります。

    • 他のスレッドがリソースを解放するために release() メソッドを呼び出した場合、現在のスレッドは許可を得ます。
    • 他のスレッドが現在のスレッドを中断した場合。 このメソッドは値を返しません。

      構文:

      release() メソッド。 許可証を解放し、セマフォに返します。 あるスレッドが許可証を取得しようとすると、セマフォは他のスレッドによって解放されたばかりのリソースを取得する許可を与える。 さらに、そのスレッドはスレッドスケジューリングの目的で考慮される。

      構文:

      availablePermits() メソッド。 このメソッドは、リソースを許可するためにセマフォで利用可能な許可証の数を返します。

      構文:

      簡単な例で上記のメソッドを理解しましょう。

      セマフォをロックとして使用する

      Javaではセマフォをロックとして使用することができます。 これは、リソースへのアクセスをロックすることを意味します。 ロックされたリソースにアクセスしたいスレッドは、リソースにアクセスする前にacquire()メソッドを呼び出してロックを取得する必要があります。 スレッドはタスクの終了後、release()メソッドを呼び出してロックを解放しなければなりません。 上限を 1 に設定することを忘れないでください。 たとえば、次のコードスニペットを考えてみましょう。

      Let’s see an example of a semaphore and use semaphore as a lock.java

      SemaphoreAsLock.java

      Output:

      Java Semaphore

      Note: 上のプログラムを実行すると、毎回異なる出力が出ています。

      Javaセマフォの例

      Javaプログラムを通して、セマフォの仕組みを理解しましょう。 以下の例では、初期許可値を3にしたセマフォクラスのコンストラクタを作成しています。

      SemaphoreExample.java

      出力:

      Java Semaphore

    コメントを残す

    メールアドレスが公開されることはありません。