자바 동시성-잠금 인터페이스

java.util.concurrent.locks.Lock 인터페이스는 동기화 된 블록과 유사한 스레드 동기화 메커니즘으로 사용됩니다. 새로운 잠금 메커니즘은 동기화 된 블록보다 더 유연하고 더 많은 옵션을 제공합니다. 잠금과 동기화 된 블록의 주요 차이점은 다음과 같습니다.

  • Guarantee of sequence− 동기화 된 블록은 대기중인 스레드에게 액세스 권한이 부여되는 시퀀스를 보장하지 않습니다. 잠금 인터페이스가 처리합니다.

  • No timeout− 잠금이 허용되지 않은 경우 동기화 된 블록에는 타임 아웃 옵션이 없습니다. 잠금 인터페이스는 이러한 옵션을 제공합니다.

  • Single method − 동기화 된 블록은 단일 메소드 내에 완전히 포함되어야하지만 잠금 인터페이스의 메소드 lock () 및 unlock ()은 다른 메소드에서 호출 될 수 있습니다.

잠금 방법

다음은 Lock 클래스에서 사용할 수있는 중요한 메서드 목록입니다.

Sr. 아니. 방법 및 설명
1

public void lock()

잠금을 획득합니다.

2

public void lockInterruptibly()

현재 스레드가 중단되지 않는 한 잠금을 획득합니다.

public Condition newCondition()

이 Lock 인스턴스에 바인딩 된 새 Condition 인스턴스를 반환합니다.

4

public boolean tryLock()

호출시 잠금이 해제 된 경우에만 잠금을 획득합니다.

5

public boolean tryLock()

호출시 잠금이 해제 된 경우에만 잠금을 획득합니다.

6

public boolean tryLock(long time, TimeUnit unit)

주어진 대기 시간 내에 잠금이 해제되고 현재 스레드가 중단되지 않은 경우 잠금을 획득합니다.

7

public void unlock()

잠금을 해제합니다.

다음 TestThread 프로그램은 Lock 인터페이스의 이러한 메서드 중 일부를 보여줍니다. 여기에서는 lock ()을 사용하여 잠금을 획득하고 unlock ()을 사용하여 잠금을 해제했습니다.

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

class PrintDemo {
   private final Lock queueLock = new ReentrantLock();

   public void print() {
      queueLock.lock();

      try {
         Long duration = (long) (Math.random() * 10000);
         System.out.println(Thread.currentThread().getName() 
            + "  Time Taken " + (duration / 1000) + " seconds.");
         Thread.sleep(duration);
      } catch (InterruptedException e) {
         e.printStackTrace();
      } finally {
         System.out.printf(
            "%s printed the document successfully.\n", Thread.currentThread().getName());
         queueLock.unlock();
      }
   }
}

class ThreadDemo extends Thread {
   PrintDemo  printDemo;

   ThreadDemo(String name,  PrintDemo printDemo) {
      super(name);
      this.printDemo = printDemo;
   }   

   @Override
   public void run() {
      System.out.printf(
         "%s starts printing a document\n", Thread.currentThread().getName());
      printDemo.print();
   }
}

public class TestThread {

   public static void main(String args[]) {
      PrintDemo PD = new PrintDemo();

      ThreadDemo t1 = new ThreadDemo("Thread - 1 ", PD);
      ThreadDemo t2 = new ThreadDemo("Thread - 2 ", PD);
      ThreadDemo t3 = new ThreadDemo("Thread - 3 ", PD);
      ThreadDemo t4 = new ThreadDemo("Thread - 4 ", PD);

      t1.start();
      t2.start();
      t3.start();
      t4.start();
   }
}

그러면 다음과 같은 결과가 생성됩니다.

산출

Thread - 1  starts printing a document
Thread - 4  starts printing a document
Thread - 3  starts printing a document
Thread - 2  starts printing a document
Thread - 1   Time Taken 4 seconds.
Thread - 1  printed the document successfully.
Thread - 4   Time Taken 3 seconds.
Thread - 4  printed the document successfully.
Thread - 3   Time Taken 5 seconds.
Thread - 3  printed the document successfully.
Thread - 2   Time Taken 4 seconds.
Thread - 2  printed the document successfully.

여기서는 Lock 인터페이스 구현으로 ReentrantLock 클래스를 사용했습니다. ReentrantLock 클래스를 사용하면 다른 메서드에 대한 잠금이 이미있는 경우에도 스레드가 메서드를 잠글 수 있습니다.