자바 동시성-ReadWriteLock 인터페이스

java.util.concurrent.locks.ReadWriteLock 인터페이스를 사용하면 한 번에 여러 스레드를 읽을 수 있지만 한 번에 하나의 스레드 만 쓸 수 있습니다.

  • Read Lock − 쓰기를 위해 ReadWriteLock을 잠근 스레드가 없으면 여러 스레드가 읽기 잠금에 액세스 할 수 있습니다.

  • Write Lock − 읽거나 쓰는 스레드가 없으면 한 스레드가 쓰기 잠금에 액세스 할 수 있습니다.

잠금 방법

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

Sr. 아니. 방법 및 설명
1

public Lock readLock()

읽기에 사용되는 잠금을 반환합니다.

2

public Lock writeLock()

쓰기에 사용되는 잠금을 반환합니다.

다음 TestThread 프로그램은 ReadWriteLock 인터페이스의 이러한 메서드를 보여줍니다. 여기서 우리는 readlock ()을 사용하여 읽기 잠금을 획득하고 writeLock ()을 사용하여 쓰기 잠금을 획득했습니다.

import java.util.concurrent.locks.ReentrantReadWriteLock;

public class TestThread {
   private static final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(true);
   private static String message = "a";

   public static void main(String[] args) throws InterruptedException {
      Thread t1 = new Thread(new WriterA());
      t1.setName("Writer A");
      
      Thread t2 = new Thread(new WriterB());
      t2.setName("Writer B");
      
      Thread t3 = new Thread(new Reader());
      t3.setName("Reader");
      t1.start();
      t2.start();
      t3.start();
      t1.join();
      t2.join();
      t3.join();
   }

   static class Reader implements Runnable {

      public void run() {
         
         if(lock.isWriteLocked()) {
            System.out.println("Write Lock Present.");
         }
         lock.readLock().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.println(Thread.currentThread().getName() +": "+ message );
            lock.readLock().unlock();
         }
      }
   }

   static class WriterA implements Runnable {

      public void run() {
         lock.writeLock().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 {
            message = message.concat("a");
            lock.writeLock().unlock();
         }
      }
   }

   static class WriterB implements Runnable {

      public void run() {
         lock.writeLock().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 {
            message = message.concat("b");
            lock.writeLock().unlock();
         }
      }
   }
}

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

산출

Writer A  Time Taken 6 seconds.
Write Lock Present.
Writer B  Time Taken 2 seconds.
Reader  Time Taken 0 seconds.
Reader: aab