Un bloqueo puede ser un mecanismo de sincronización de subprocesos más flexible y complicado que el bloque sincronizado estándar. Un candado puede ser una herramienta para controlar el acceso a un recurso compartido por varios subprocesos. Por lo general, un bloqueo proporciona acceso exclusivo a un recurso compartido: solo un subproceso a la vez puede adquirir el bloqueo y todos los que acceden al recurso compartido requieren que el bloqueo se adquiera primero. Sin embargo, algunos bloqueos pueden permitir el acceso simultáneo a un recurso compartido, como el bloqueo de lectura de un ReadWriteLock.
// Example of lock interface Lock lock = new ReentrantLock(); lock.lock(); // critical section lock.unlock();
Métodos en la interfaz de bloqueo
Hay ciertos métodos en una interfaz de bloqueo. Vamos a ver esos junto con sus modificadores:
MODIFICADORES | DESCRIPCIÓN |
---|---|
vacío | lock() – Adquiere el bloqueo si está disponible; si el bloqueo no está disponible, un hilo se bloquea hasta que se libera el bloqueo |
lockInterruptably() – Es similar a lock() pero adquiere el bloqueo a menos que se interrumpa el hilo | |
unlock() – Como sugiere el nombre, simplemente libera la instancia de bloqueo | |
condición | newCondition(): simplemente devuelve la nueva instancia de condición |
booleano | tryLock(): intenta acumular el bloqueo inmediatamente, devuelve verdadero si el bloqueo tiene éxito |
tryLock(largo tiempo, unidad TimeUnit) – A menudo es casi como tryLock(), excepto que espera el tiempo de espera antes de abandonar el intento de acumular el bloqueo. |
Implementación de bloqueos
Veamos cómo podemos implementar algunos bloqueos en Java:
ReadWriteLock readWriteLock = new ReentrantReadWriteLock(); readWriteLock.readLock().lock(); // .... ......// readWriteLock.readLock().unlock(); readWriteLock.writeLock().lock(); // only one writer can enter this section, // and only if no threads are currently reading. readWriteLock.writeLock().unlock();
A continuación se muestra la implementación del método readWriteLock():
Java
// Implementation of ReadWriteLock in Java import java.io.*; import java.util.ArrayList; import java.util.List; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; class GFG<O> { private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock(); private final Lock writeLock = readWriteLock.writeLock(); private final Lock readLock = readWriteLock.readLock(); private final List<O> list = new ArrayList<>(); // setElement function sets // i.e., write the element to the thread public void setElement(O o) { // acquire the thread for writing writeLock.lock(); try { list.add(o); System.out.println( "Element by thread " + Thread.currentThread().getName() + " is added"); } finally { // To unlock the acquired write thread writeLock.unlock(); } } // getElement function prints // i.e., read the element from the thread public O getElement(int i) { // acquire the thread for reading readLock.lock(); try { System.out.println( "Elements by thread " + Thread.currentThread().getName() + " is printed"); return list.get(i); } finally { // To unlock the acquired read thread readLock.unlock(); } } public static void main(String[] args) { GFG<String> gfg = new GFG<>(); gfg.setElement("Hi"); gfg.setElement("Hey"); gfg.setElement("Hello"); System.out.println("Printing the last element : " + gfg.getElement(2)); } }
Element by thread main is added Element by thread main is added Element by thread main is added Elements by thread main is printed Printing the last element : Hello
public class lockImplement { //... ReentrantLock lock = new ReentrantLock(); int counter = 0; public void testing() { lock.lock(); try { // Critical section here count++; } finally { lock.unlock(); } } //... }
A continuación se muestra la implementación del método reentrantLock():
Java
// Java code to illustrate Reentrant Locks import java.text.SimpleDateFormat; import java.util.Date; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.locks.ReentrantLock; class worker implements Runnable { String name; ReentrantLock re; public worker(ReentrantLock rl, String n) { re = rl; name = n; } public void run() { boolean done = false; while (!done) { // Getting Outer Lock boolean ans = re.tryLock(); // Returns True if lock is free if (ans) { try { Date d = new Date(); SimpleDateFormat ft = new SimpleDateFormat("hh:mm:ss"); System.out.println( "task name - " + name + " outer lock acquired at " + ft.format(d) + " Doing outer work"); Thread.sleep(1500); // Getting Inner Lock re.lock(); try { d = new Date(); ft = new SimpleDateFormat( "hh:mm:ss"); System.out.println( "task name - " + name + " inner lock acquired at " + ft.format(d) + " Doing inner work"); System.out.println( "Lock Hold Count - " + re.getHoldCount()); Thread.sleep(1500); } catch (InterruptedException e) { e.printStackTrace(); } finally { // Inner lock release System.out.println( "task name - " + name + " releasing inner lock"); re.unlock(); } System.out.println("Lock Hold Count - " + re.getHoldCount()); System.out.println("task name - " + name + " work done"); done = true; } catch (InterruptedException e) { e.printStackTrace(); } finally { // Outer lock release System.out.println( "task name - " + name + " releasing outer lock"); re.unlock(); System.out.println("Lock Hold Count - " + re.getHoldCount()); } } else { System.out.println("task name - " + name + " waiting for lock"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } } } public class test { static final int MAX_T = 2; public static void main(String[] args) { ReentrantLock rel = new ReentrantLock(); ExecutorService pool = Executors.newFixedThreadPool(MAX_T); Runnable w1 = new worker(rel, "Job1"); Runnable w2 = new worker(rel, "Job2"); Runnable w3 = new worker(rel, "Job3"); Runnable w4 = new worker(rel, "Job4"); pool.execute(w1); pool.execute(w2); pool.execute(w3); pool.execute(w4); pool.shutdown(); } }
Producción:
task name - Job2 waiting for lock task name - Job1 outer lock acquired at 09:49:42 Doing outer work task name - Job2 waiting for lock task name - Job1 inner lock acquired at 09:49:44 Doing inner work Lock Hold Count - 2 task name - Job2 waiting for lock task name - Job2 waiting for lock task name - Job1 releasing inner lock Lock Hold Count - 1 task name - Job1 work done task name - Job1 releasing outer lock Lock Hold Count - 0 task name - Job3 outer lock acquired at 09:49:45 Doing outer work task name - Job2 waiting for lock task name - Job3 inner lock acquired at 09:49:47 Doing inner work Lock Hold Count - 2 task name - Job2 waiting for lock task name - Job2 waiting for lock task name - Job3 releasing inner lock Lock Hold Count - 1 task name - Job3 work done task name - Job3 releasing outer lock Lock Hold Count - 0 task name - Job4 outer lock acquired at 09:49:48 Doing outer work task name - Job2 waiting for lock task name - Job4 inner lock acquired at 09:49:50 Doing inner work Lock Hold Count - 2 task name - Job2 waiting for lock task name - Job2 waiting for lock task name - Job4 releasing inner lock Lock Hold Count - 1 task name - Job4 work done task name - Job4 releasing outer lock Lock Hold Count - 0 task name - Job2 outer lock acquired at 09:49:52 Doing outer work task name - Job2 inner lock acquired at 09:49:53 Doing inner work Lock Hold Count - 2 task name - Job2 releasing inner lock Lock Hold Count - 1 task name - Job2 work done task name - Job2 releasing outer lock Lock Hold Count - 0
Nota: Es posible que el programa no funcione en un IDE en línea debido a la llamada de suspensión.
Publicación traducida automáticamente
Artículo escrito por mayanktyagi1709 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA