Рубрики
Без рубрики

Пример блокировки Java – Повторная блокировка

Пример блокировки Java, Повторная блокировка в Java, API блокировки параллелизма java, блокировка java против синхронизации, java.util.concurrent.блокировки, объект блокировки java.

Автор оригинала: Pankaj Kumar.

Добро пожаловать в учебник по примерам блокировки Java. Обычно при работе с многопоточной средой мы используем synchronized для обеспечения безопасности потоков .

Блокировка Java

В большинстве случаев ключевое слово synchronized-это правильный путь, но у него есть некоторые недостатки, которые приводят к включению API блокировки в пакет параллелизма Java. API параллелизма Java 1.5 придумал java.util.concurrent.блокирует пакет с блокировкой интерфейса и некоторыми классами реализации для улучшения механизма блокировки объектов.

Некоторые важные интерфейсы и классы в Java Lock API являются:

  1. Блокировка : Это базовый интерфейс для API блокировки. Он предоставляет все функции синхронизированного ключевого слова с дополнительными способами создания различных условий для блокировки, обеспечивая тайм-аут для потока для ожидания блокировки. Некоторые из важных методов: блокировка() для получения блокировки, разблокировка() для снятия блокировки, tryLock() для ожидания блокировки в течение определенного периода времени, NewCondition() для создания условия и т.д.
  2. Условие : Объекты условия похожи на Объект ожидание-уведомление модель с дополнительной функцией для создания различных наборов ожидания. Объект Условия всегда создается объектом Блокировки. Некоторые из важных методов-это await (), похожий на wait() и signal (), signalAll (), похожий на notify() и notifyAll() методы.
  3. ReadWriteLock : Он содержит пару связанных блокировок, одну для операций только для чтения, а другую для записи. Блокировка чтения может удерживаться одновременно несколькими потоками чтения до тех пор, пока нет потоков записи. Блокировка записи является эксклюзивной.
  4. ReentrantLock : Это наиболее широко используемый класс реализации интерфейса блокировки. Этот класс реализует интерфейс блокировки аналогично ключевому слову synchronized. Помимо реализации интерфейса блокировки, ReentrantLock содержит некоторые служебные методы для получения потока, удерживающего блокировку, потоков, ожидающих получения блокировки и т.д.

    синхронизированные блоки являются реентерабельными по своей природе, т. Е. Если поток заблокировал объект монитора, и если другой синхронизированный блок требует блокировки того же объекта монитора, поток может ввести этот блок кода. Я думаю, что именно по этой причине имя класса должно быть повторно заблокировано. Давайте разберемся в этой функции на простом примере.

    Если поток вводит foo(), он блокирует тестовый объект, поэтому, когда он пытается выполнить метод bar (), потоку разрешается выполнять метод bar (), поскольку он уже удерживает блокировку тестового объекта, т. Е. такой же, как синхронизированный(это).

Пример блокировки Java – Повторная блокировка на Java

Теперь давайте рассмотрим простой пример, в котором мы заменим ключевое слово synchronized API блокировки Java.

Допустим, у нас есть класс ресурсов с некоторой операцией, в которой мы хотим, чтобы она была потокобезопасной, и некоторыми методами, в которых потокобезопасность не требуется.

package com.journaldev.threads.lock;

public class Resource {

	public void doSomething(){
		//do some operation, DB read, write etc
	}
	
	public void doLogging(){
		//logging, no need for thread safety
	}
}

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

package com.journaldev.threads.lock;

public class SynchronizedLockExample implements Runnable{

	private Resource resource;
	
	public SynchronizedLockExample(Resource r){
		this.resource = r;
	}
	
	@Override
	public void run() {
		synchronized (resource) {
			resource.doSomething();
		}
		resource.doLogging();
	}
}

Обратите внимание, что я использую синхронизированный блок для получения блокировки объекта ресурсов. Мы могли бы создать фиктивный объект в классе и использовать его для блокировки.

Теперь давайте посмотрим, как мы можем использовать API блокировки java и переписать вышеприведенную программу без использования ключевого слова synchronized. Мы будем использовать ReentrantLock в java.

package com.journaldev.threads.lock;

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

public class ConcurrencyLockExample implements Runnable{

	private Resource resource;
	private Lock lock;
	
	public ConcurrencyLockExample(Resource r){
		this.resource = r;
		this.lock = new ReentrantLock();
	}
	
	@Override
	public void run() {
		try {
			if(lock.tryLock(10, TimeUnit.SECONDS)){
			resource.doSomething();
			}
		} catch (InterruptedException e) {
			e.printStackTrace();
		}finally{
			//release lock
			lock.unlock();
		}
		resource.doLogging();
	}

}

Как вы можете видеть, я использую метод tryLock (), чтобы убедиться, что мой поток ожидает только определенное время, и если он не получает блокировку объекта, он просто регистрируется и выходит. Еще один важный момент, который следует отметить,-это использование блока try-finally, чтобы убедиться, что блокировка снята, даже если вызов метода doSomething() вызывает какое-либо исключение.

Блокировка Java против синхронизации

Основываясь на приведенных выше деталях и программе, мы можем легко сделать вывод о следующих различиях между блокировкой Java и синхронизацией.

  1. API блокировки Java обеспечивает большую видимость и возможности блокировки, в отличие от синхронизации, когда поток может бесконечно ждать блокировки, мы можем использовать tryLock (), чтобы убедиться, что поток ожидает только определенное время.
  2. Код синхронизации намного чище и прост в обслуживании, в то время как при блокировке мы вынуждены блокировать попытку, чтобы убедиться, что блокировка снята, даже если между вызовами методов lock() и unlock() возникает некоторое исключение.
  3. блоки или методы синхронизации могут охватывать только один метод, в то время как мы можем получить блокировку в одном методе и освободить ее в другом методе с помощью API блокировки.
  4. ключевое слово synchronized не обеспечивает справедливости, в то время как мы можем установить справедливость в значение true при создании объекта ReentrantLock, чтобы самый длинный ожидающий поток получил блокировку первым.
  5. Мы можем создать разные условия для блокировки, и разные потоки не могут ждать() для разных условий.

Это все для примера блокировки Java, повторной блокировки в java и сравнительного анализа с ключевым словом synchronized.