Интерфейс ReadWriteLock
Интерфейс ReadWriteLock из пакета
java.util.concurrent.locks разделяет
обычную блокировку на две отдельные: блокировку
для чтения и блокировку для записи. Блокировку
для чтения могут одновременно удерживать несколько
потоков, если ни один поток не удерживает
блокировку для записи. Блокировку для записи
может удерживать только один поток, и в это
время ни один поток не может удерживать
блокировку для чтения. Метод readLock
возвращает блокировку для чтения, а метод
writeLock - блокировку для записи.
Основной реализацией интерфейса является класс
ReentrantReadWriteLock.
Синтаксис
ReadWriteLock lock = new ReentrantReadWriteLock();
Lock readLock = lock.readLock();
Lock writeLock = lock.writeLock();
Пример
Давайте создадим разделяемую переменную и защитим её блокировками чтения и записи. Сначала выполним чтение значения из нескольких потоков одновременно:
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class Main
{
private static int value = 5;
private static final ReadWriteLock lock = new ReentrantReadWriteLock();
public static void main(String[] args)
{
Runnable reader = () -> {
lock.readLock().lock();
try
{
System.out.println(Thread.currentThread().getName() + " read: " + value);
}
finally
{
lock.readLock().unlock();
}
};
Thread t1 = new Thread(reader, "Thread-1");
Thread t2 = new Thread(reader, "Thread-2");
t1.start();
t2.start();
}
}
Результат выполнения кода:
Thread-1 read: 5
Thread-2 read: 5
Пример
Теперь давайте выполним запись значения. Блокировка записи не даст другим потокам читать или писать в это время:
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class Main
{
private static int value = 5;
private static final ReadWriteLock lock = new ReentrantReadWriteLock();
public static void main(String[] args)
{
Runnable writer = () -> {
lock.writeLock().lock();
try
{
value = value + 1;
System.out.println(Thread.currentThread().getName() + " wrote: " + value);
}
finally
{
lock.writeLock().unlock();
}
};
Thread t1 = new Thread(writer, "Thread-1");
Thread t2 = new Thread(writer, "Thread-2");
t1.start();
t2.start();
}
}
Результат выполнения кода:
Thread-1 wrote: 6
Thread-2 wrote: 7
Пример
Давайте проверим, сколько потоков одновременно
удерживают блокировку чтения, с помощью метода
getReadLockCount класса
ReentrantReadWriteLock:
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class Main
{
public static void main(String[] args)
{
ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
lock.readLock().lock();
lock.readLock().lock();
int res = lock.getReadLockCount();
System.out.println(res);
lock.readLock().unlock();
lock.readLock().unlock();
}
}
Результат выполнения кода:
2
Смотрите также
-
класс
ReentrantReadWriteLock,
который является основной реализацией -
интерфейс
Lock,
который представляет обычную блокировку -
класс
ReentrantLock,
который реализует повторную блокировку -
ключевое слово
synchronized,
которое обеспечивает синхронизацию потоков