ホームページ  >  記事  >  Java  >  ReentrantLock クラスの使用法の概要

ReentrantLock クラスの使用法の概要

不言
不言転載
2019-03-30 10:40:282537ブラウズ

この記事では、Java での ReentrantLock クラスの使用法を紹介します。一定の参考値があります。必要な友人は参照してください。お役に立てれば幸いです。

Java マルチスレッドでは、synchronized キーワードを使用して複数のスレッド間の同期と相互排他を実現できますが、JDK 1.5 で追加された新しい ReentrantLock クラスでも同様の効果を実現でき、機能も拡張されています。スニッフィング ロック、多方向分岐通知、公平なロックおよび不公平なロック (デフォルト) 機能など、より強力で、同期よりも柔軟に使用できます。

ReentrantLock を使用して同期を実現します

public class MyService {
    private Lock lock = new ReentrantLock();
    public void testMethod() {
        lock.lock();
        for (int i = 0; i < 10; i++){
            System.out.println("ThreadName=" + Thread.currentThread().getName() + (" " + (i + 1)));
        }
        lock.unlock();
    }
}
public class MyThread extends Thread {
    private MyService myService;
    public MyThread(MyService myService) {
        this.myService = myService;
    }
    @Override
    public void run() {
        myService.testMethod();
    }
}
public static void main(String[] args) throws IOException, InterruptedException {
MyService myService = new MyService();
MyThread myThreadA = new MyThread(myService);
        MyThread myThreadB = new MyThread(myService);
        MyThread myThreadC = new MyThread(myService);
        MyThread myThreadD = new MyThread(myService);
        MyThread myThreadE = new MyThread(myService);

        myThreadA.start();
        myThreadB.start();
        myThreadC.start();
        myThreadD.start();
        myThreadE.start();

    }

ReentrantLock オブジェクトの lock() メソッドを呼び出してロックを取得し、unLock() メソッドを呼び出してロックを解放します。

実行結果から判断すると、ロックは解放されます。現在のスレッドが印刷を終了した後、他のスレッドは印刷を続行できます。現在のスレッドがすでにロックを保持しているため、スレッドによって印刷されたデータはグループ化されて印刷されますが、スレッド間の印刷順序はランダムです。

条件を使用して待機/通知を実装する

キーワード synchronized を wait() メソッドおよび Notice() /notifyall() メソッドと組み合わせて待機/通知モードを実装できます。 () メソッドが呼び出されると、JVM は実行する WAITNG 状態のスレッドをランダムに選択します。 .

Condition の使用はより柔軟で、「選択的通知」を実装でき、どのスレッドを実行するかを指定できます。ウェイクアップし、どのスレッドが待機を継続するかを指定します。

public class MyService {

    private Lock lock = new ReentrantLock();
    public Condition conditionA = lock.newCondition();
    public Condition conditionB = lock.newCondition();

    public void awaitA() throws InterruptedException {
        lock.lock();

        System.out.println("begin awaitA 时间" + System.currentTimeMillis() + "ThreadName=" + Thread.currentThread().getName());

        conditionA.await();

        System.out.println("end awaitA 时间" + System.currentTimeMillis() + "ThreadName=" + Thread.currentThread().getName());

        lock.unlock();
    }

    public void awaitB() throws InterruptedException {
        lock.lock();

        System.out.println("begin awaitB 时间" + System.currentTimeMillis() + "ThreadName=" + Thread.currentThread().getName());

        conditionB.await();

        System.out.println("end awaitB 时间" + System.currentTimeMillis() + "ThreadName=" + Thread.currentThread().getName());

        lock.unlock();
    }

    public void  signalAll_A() throws InterruptedException {
        lock.lock();
        System.out.println("begin signalAll_A 时间" + System.currentTimeMillis() + "ThreadName=" + Thread.currentThread().getName());

        conditionA.signalAll();

        lock.unlock();
    }

    public void  signalAll_B() throws InterruptedException {
        lock.lock();
        System.out.println("begin signalAll_B 时间" + System.currentTimeMillis() + "ThreadName=" + Thread.currentThread().getName());

        conditionB.signalAll();

        lock.unlock();
    }
}
public class ThreadA extends Thread {

    private MyService myService;
    public ThreadA(MyService myService) {
        this.myService = myService;
    }

    @Override
    public void run() {
        try {
            myService.awaitA();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
public class ThreadB extends Thread {

    private MyService myService;

    public ThreadB(MyService myService) {
        this.myService = myService;
    }

    @Override
    public void run() {
        try {
            myService.awaitB();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
    public static void main(String[] args) throws IOException, InterruptedException {

        MyService myService = new MyService();

        ThreadA threadA = new ThreadA(myService);
        threadA.setName("a");
        threadA.start();

        ThreadB threadB = new ThreadB(myService);
        threadB.setName("b");
        threadB.start();

        Thread.sleep(3000);
        myService.signalAll_A();

    }
  • Object クラスの wait() メソッドは、Condition クラスの await() メソッドと同等です。
  • The wait( Object クラスの (long timeout) メソッドは、Condition クラスの await(long time, TimeUnit Unit) メソッドと同等です。
  • Object クラスの Notice() メソッドは、次の signal() メソッドと同等です。 Condition クラス。
  • Object クラスの NoticeAll() メソッドは、Condition クラスの signalAll() メソッドと同等です。

実行結果から判断すると、スレッド a とmyService.signalAll_A() メソッドが実行されると、スレッド a は実行を継続しますが、スレッド b はまだ待機状態にあります。

共通メソッド

ReentrantLock クラス

int getHoldCount() lock() メソッドが呼び出された回数をクエリします。

final int getQueueLength() ロックを待機しているスレッドの数を推定します。たとえば、スレッドが 5 つ、スレッドが 1 つあります。スレッドは最初に await() メソッドを実行し、このメソッドを呼び出した後の戻り値は 4 で、4 つのスレッドが同時にロックが解放されるのを待っていることを示します。このロック 特定の条件を待機しているスレッドの推定数。たとえば、5 つのスレッドがあり、各スレッドが同じ条件オブジェクトの await() メソッドを実行する場合、このメソッドを呼び出したときに返される値は 5 です。

final boolean hasQueuedThreads() このロックを待機しているスレッドがあるかどうかを判断します。

final boolean hasQueuedThread(Thread thread) 指定されたスレッドがこのロックの取得を待機しているかどうかを判断します。

boolean hasWaiters(Condition 条件) スレッドを決定します await() メソッドを呼び出しましたか。

void lockInterruptibly() は、現在のスレッドが中断されない限り、InterruptedException をスローしてロックを取得します。

Condition class

void awaitUninterruptibly() と await( ) の違いは、interrupt() メソッドが呼び出されたときに InterrputedException 例外がスローされないことです。その他のエキサイティングなコンテンツについては、PHP 中国語 Web サイトのチュートリアル

列にある

Java ビデオに注目してください。

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

声明:
この記事はsegmentfault.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。