Concurrence Java - Interface ReadWriteLock

Une interface java.util.concurrent.locks.ReadWriteLock permet à plusieurs threads de lire à la fois, mais un seul thread peut écrire à la fois.

  • Read Lock - Si aucun thread n'a verrouillé le ReadWriteLock pour l'écriture, plusieurs threads peuvent accéder au verrou de lecture.

  • Write Lock - Si aucun thread ne lit ou n'écrit, un thread peut accéder au verrou d'écriture.

Verrouiller les méthodes

Voici la liste des méthodes importantes disponibles dans la classe Lock.

N ° Sr. Méthode et description
1

public Lock readLock()

Renvoie le verrou utilisé pour la lecture.

2

public Lock writeLock()

Renvoie le verrou utilisé pour l'écriture.

Exemple

Le programme TestThread suivant illustre ces méthodes de l'interface ReadWriteLock. Ici, nous avons utilisé readlock () pour acquérir le verrou de lecture et writeLock () pour acquérir le verrou d'écriture.

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();
         }
      }
   }
}

Cela produira le résultat suivant.

Production

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