Учебники

Параллелизм Java – интерфейс блокировки

Интерфейс java.util.concurrent.locks.Lock используется в качестве механизма синхронизации потоков, аналогичного синхронизированным блокам. Новый механизм блокировки является более гибким и предоставляет больше возможностей, чем синхронизированный блок. Основные различия между замком и синхронизированным блоком следующие:

  • Гарантия последовательности – Синхронизированный блок не дает никакой гарантии последовательности, в которой ожидающему потоку будет предоставлен доступ. Интерфейс блокировки обрабатывает это.

  • Нет тайм-аута. Синхронизированный блок не имеет опции тайм-аута, если блокировка не предоставлена. Интерфейс блокировки предоставляет такую ​​возможность.

  • Одиночный метод – Синхронизированный блок должен полностью содержаться в одном методе, в то время как методы интерфейса блокировки lock () и unlock () могут вызываться в разных методах.

Гарантия последовательности – Синхронизированный блок не дает никакой гарантии последовательности, в которой ожидающему потоку будет предоставлен доступ. Интерфейс блокировки обрабатывает это.

Нет тайм-аута. Синхронизированный блок не имеет опции тайм-аута, если блокировка не предоставлена. Интерфейс блокировки предоставляет такую ​​возможность.

Одиночный метод – Синхронизированный блок должен полностью содержаться в одном методе, в то время как методы интерфейса блокировки lock () и unlock () могут вызываться в разных методах.

Методы блокировки

Ниже приведен список важных методов, доступных в классе Lock.

Sr.No. Метод и описание
1

общедоступная блокировка недействительности ()

Приобретает замок.

2

public void lockInterruptibly ()

Получает блокировку, если текущий поток не прерывается.

3

публичное состояние newCondition ()

Возвращает новый экземпляр Condition, связанный с этим экземпляром Lock.

4

public boolean tryLock ()

Получает блокировку, только если она свободна на момент вызова.

5

public boolean tryLock ()

Получает блокировку, только если она свободна на момент вызова.

6

public boolean tryLock (долгое время, модуль TimeUnit)

Получает блокировку, если она свободна в течение заданного времени ожидания, и текущий поток не был прерван.

7

общедоступная разблокировка void ()

Снимает блокировку.

общедоступная блокировка недействительности ()

Приобретает замок.

public void lockInterruptibly ()

Получает блокировку, если текущий поток не прерывается.

публичное состояние newCondition ()

Возвращает новый экземпляр Condition, связанный с этим экземпляром Lock.

public boolean tryLock ()

Получает блокировку, только если она свободна на момент вызова.

public boolean tryLock ()

Получает блокировку, только если она свободна на момент вызова.

public boolean tryLock (долгое время, модуль TimeUnit)

Получает блокировку, если она свободна в течение заданного времени ожидания, и текущий поток не был прерван.

общедоступная разблокировка void ()

Снимает блокировку.

пример

Следующая программа TestThread демонстрирует некоторые из этих методов интерфейса Lock. Здесь мы использовали lock (), чтобы получить блокировку, и unlock (), чтобы снять блокировку.

Live Demo

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.

Мы использовали класс ReentrantLock в качестве реализации интерфейса блокировки здесь. Класс ReentrantLock позволяет потоку заблокировать метод, даже если он уже заблокирован другим методом.