ホームページ >Java >&#&チュートリアル >Java のロック API の概要

Java のロック API の概要

Linda Hamilton
Linda Hamiltonオリジナル
2024-12-31 18:59:14473ブラウズ

Overview of Lock API in java

共有リソースへのアクセスを管理することは、同時プログラミングにおいてデータの一貫性を確保するために重要です。従来の同期キーワードには、公平性、すぐにロックを取得する、特定の時間までロックを取得するなどの複雑なシナリオに対する柔軟性がありません。これらの制限に対処するために、Lock、ReadWriteLock、および StampedLock API が Java 1.5 で導入され、開発者が処理するための優れた制御を提供します。共有リソースへのアクセス。これらは java.util.concurrent パッケージの一部です。

ロックAPI

Lock API はインターフェイスであり、スレッドの同期を処理するための以下のメソッドを提供します。

  • void lock() ロックを取得するために使用されます。ロックが利用できない場合、スレッドはロックが取得されるまでブロックされます。
  • void lockInterruptibly() lock() と同じですが、このスレッドは中断できます。
  • boolean tryLock() ロックが取得された場合は true を返します。それ以外の場合は false。ロックが付与されない場合、スレッドはブロックされません。
  • boolean tryLock(long timeout, TimeUnit単位) tryLock()と同じですが、指定した時間だけ待機します。
  • voidunlock()ロックを解除します。
  • Condition newCondition() 重要な部分の実行中に、スレッドが何らかの条件が発生するのを待機する機能を提供します。

リエントラントロック

  • ReentrantLock クラスは Lock インターフェースを実装します。 
  • 再入可能なロックにより、スレッドは複数回ロックを取得し、複数回ロックを解放できます。
  • 公平性ポリシーが必要な場合は、ReentrantLock のパラメーター化されたコンストラクターを使用します。
  • 公平性が有効な場合、最も長く待機しているスレッドにロックへのアクセスが与えられるようになります。
  • デッドロック状況を回避するには、finally ブロックを使用してロックを解放します。
ReentrantLock lock = new ReentrantLock(true); //fair lock
public void methodExecution() {
    lock.lock();
    try {
        // Critical section here
    } finally {
        lock.unlock();
    }
}

読み取り書き込みロック API

ReadWriteLock API はインターフェイスであり、読み取りおよび書き込みシナリオを維持するためのロックのペアを維持します。書き込み側が存在しない場合、読み取りロックは複数のスレッドによって同時に保持される可能性があります。書き込みロックは排他的です。

  • Lock readLock() - 読み取りに使用されるロックを返します。
  • Lock writeLock() - 書き込みに使用されるロックを返します。

重要なルール

  • 読み取りロックがある場合は、書き込みロックを取得できません。
  • 書き込みロックがある場合、他のスレッドで読み取りロックを取得することはできません。
  • 書き込みロックがある場合は、同じスレッドで別の書き込みロックを取得できます。
  • 他の読み取りまたは書き込みロックがアクティブでない場合、書き込みロックは許可されます。
  • 書き込みロックを待機している間、他のスレッドからの新しい読み取りロックは許可されません。

リエントラント読み取り書き込みロック

  • ReentrantReadWriteLock クラスは ReadWriteLock インターフェイスを実装します。
  • 書き込みよりも多くの読み取り比較がある場合に便利です。

例: マイクロサービス通信で、サービス B がサービス A からの JWT を期待しているとします。JWT はサービス A によって生成され、数分間キャッシュ可能です。このシナリオでは、ReentrantReadWriteLock の方が便利です。トークンの有効期限が切れているか、期限切れが近づいている場合は、トークンを更新できます。読み取り不足を避けるために、ここでは読み取りロックを取得していません。

ReentrantLock lock = new ReentrantLock(true); //fair lock
public void methodExecution() {
    lock.lock();
    try {
        // Critical section here
    } finally {
        lock.unlock();
    }
}

StampedLock API

StampedLock は Java 8 で導入されたクラスです。 3 つのロック モードをサポートし、ロックを解除するために使用されるスタンプを返します。ロックのアップグレードが可能になります。

  1. 読み取りロック 複数のスレッドによる同時読み取りを許可します。
  2. Write Lock 書き込みに使用されるロックを返します。
  3. オプティミスティック読み取りロック 従来の読み取りロックを取得せずにスレッドが読み取りを行えるようにします。これにより、競合が回避され、パフォーマンスが向上します。
  • long writeLock() 排他的ロックを取得し、利用可能になるまで必要に応じてブロックします。
  • voidunlockWrite(long stamp) 書き込みロックを解除します。
  • long readLock() 読み取りロックを取得し、書き込みロックが進行中の場合はブロックします。
  • voidunlockRead(long stamp) 読み取りロックを解除します。
  • long tryOptimisticRead() 後で検証できるスタンプを返します。排他的にロックされている場合はゼロを返します。
  • boolean validate(long stamp) 指定されたスタンプの発行以降、ロックが排他的に取得されていない場合 (書き込みロック)、true を返します。それ以外の場合は false。
  • long tryConvertToWriteLock(long stamp) 読み取りロックまたはオプティミスティック ロックを書き込みロックにアップグレードします。利用可能になるまでブロックします。

キーポイント:

  • これはリエントラントではありません。つまり、ロックを保持しているスレッドは再びロックを取得できません。
  • 条件には対応していません。
  • 公平性をサポートしていません。
String jwt = JwtUtil.generateJwt();
ReadWriteLock lock = new ReentrantReadWriteLock();
Lock writeLock = lock.writeLock();
Lock readLock = lock.readLock();

public String getJwt(String key, String value) {
    if (StringUtils.hasLength(jwt)) {
        if (JwtUtil.isJwtEligibleToRenew(jwt)) {
            generateJwt();
        }
    } else {
        generateJwt();
    }
    return this.jwt;
}

public void generateJwt() {
    this.writeLock.lock(); //write lock
    try {
        if (JwtUtil.isJwtEligibleToRenew(jwt)) {
            this.jwt = JwtUtil.generateJwt();
        }
    } finally {
        this.writeLock.unlock(); //release write lock
    }
}

楽観的な読み取りの例。これにより、スレッドは従来の読み取りロックを取得せずに読み取ることができるため、ロックの競合が回避され、パフォーマンスが向上します。オプティミスティック読み取りロック時間を取得した後に書き込みロックが取得された場合、 validate() は false を返します。それ以外の場合は true になります。

public void readAndWrite() {
    long l = this.stampedLock.readLock();
    try {
        //critical section
    } finally {
        this.stampedLock.unlock(l);
    }

    long w = this.stampedLock.writeLock();
    try {
        //critical section
    } finally {
        this.stampedLock.unlock(w);
    }
}

コーディングと学習を楽しんでください !!!

ご質問がございましたら、コメントしてください。

以上がJava のロック API の概要の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。