>  기사  >  Java  >  ReentrantLock 클래스 사용법 소개

ReentrantLock 클래스 사용법 소개

不言
不言앞으로
2019-03-30 10:40:282519검색

이 글은 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() 메서드를 호출하여 잠금을 해제합니다.#🎜🎜 #

실행 결과에서 현재 스레드가 인쇄를 마친 후 잠금이 해제되고 다른 스레드가 인쇄를 계속할 수 있습니다. 현재 스레드가 이미 잠금을 보유하고 있기 때문에 스레드가 인쇄한 데이터는 그룹으로 인쇄됩니다. 스레드 간 인쇄 순서는 무작위입니다.

조건을 사용하여 대기/알림 구현

동기화된 키워드는 wait() 및 inform()/notifyall()과 결합될 수 있습니다. 대기/알림 모드를 달성하기 위한 메소드가 있지만 이를 사용할 때 통지() 메소드를 호출하면 JVM이 WAITNG 상태의 스레드를 무작위로 선택하여 실행할 것입니다.

조건을 사용하면 더 유연하게 구현할 수 있습니다. 선택적 알림"을 ​​사용하여 깨울 스레드와 계속할 스레드를 지정할 수 있습니다. Wait.

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() 메서드는 wait()와 동일합니다. Condition 클래스의 wait(긴 시간, TimeUnit 단위) 메서드는 Condition 클래스의 wait(긴 시간, TimeUnit 단위) 메서드와 동일합니다.
    #🎜🎜 #Object 클래스의 inform() 메서드는 Condition 클래스의 signal() 메서드와 동일합니다.
  • # 🎜🎜#Object 클래스의 informAll() 메서드는 Condition 클래스의 signalAll() 메서드와 동일합니다. 조건 클래스.
  • 실행 결과로 보면 스레드 a와 b가 일시 중지되었습니다. myService가 .signalAll_A() 메서드를 실행하면 스레드 a는 계속 실행되고 스레드 b는 아직 실행 중입니다. 대기 상태.
  • Common 메소드
  • ReentrantLock class

int getHoldCount () lock() 메소드가 호출된 횟수를 쿼리합니다. 🎜🎜#

final int getQueueLength() 잠금을 기다리는 스레드 수를 추정합니다. 예를 들어 5개의 스레드가 있고 1개의 스레드가 먼저 wait() 메서드를 실행한 다음 호출한 후 이 메서드의 반환 값을 반환합니다. 4이며, 동시에 잠금이 해제되기를 기다리는 스레드가 4개 있음을 나타냅니다.

int getWaitQueueLength(Condition Condition)와 관련된 주어진 조건을 기다리는 스레드 수의 추정치를 반환합니다. 예를 들어 5개의 스레드가 있고 각 스레드가 동일한 조건 개체의 wait() 메서드를 실행하는 경우 이 메서드를 호출할 때 반환되는 값은 5입니다.

final boolean hasQueuedThreads() 스레드가 있는지 확인합니다. 이 잠금을 기다립니다.

final boolean hasQueuedThread(Thread thread) 지정된 스레드가 이 잠금을 획득하기 위해 기다리고 있는지 확인합니다.

boolean hasWaiters(조건 조건 ) 스레드가 wait() 메서드를 호출했는지 확인합니다.

void lockInterruptible()은 현재 스레드가 중단되지 않는 한 잠금을 획득하기 위해 InterruptedException을 발생시킵니다.

Condition class#🎜 🎜#

void waitUninterruptously() 및 wait( ) 차이점은 InterrpulatedException 예외가 #JavaVideoTutorial

열에서 발생하지 않는다는 것입니다.

위 내용은 ReentrantLock 클래스 사용법 소개의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 segmentfault.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제