ReadWriteLock в Java

ReadWriteLock – класс содержащий 2 лока: один для чтения, другой для записи.

Часто бывает так, что один поток пишет в ресурс, а много других потоков читают из него.

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

Пример программы:

import java.io.*; import java.util.*; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; public class RedWrtLockExample { static long numOfOperations=10000000000L; public static void main(String[] args) { CommonResource commonResource = new CommonResource(); //объект ресурса for (int i = 1; i < 4; i++){ //Запускаем 3 потока и передаем в каждый из них //ресурс общий для потоков. Thread t = new Thread(new CountThread(commonResource)); t.setName("Thread " + i); t.start(); } //5 раз записать 10 млрд в commonResource.value for (int i = 0; i < 5; i++) { //Здесь начинается запись в ресурс потоком мейн //и пока происходит запись в ресурс потоком мейн //другие потоки читать из ресурса не смогут. commonResource.write(); try{ Thread.sleep(100); } catch(InterruptedException e){} } } static class CommonResource { long value; private final ReadWriteLock lock = new ReentrantReadWriteLock(); void write() { //здесь происходит writeLock().lock() на время //записи десяти млрд блокируем все другие потоки, //которые дошли до readLock().lock() в этом объекте lock.writeLock().lock(); for (long i = 0; i < numOfOperations; i++){ value++; } //запускаются залоченные в read lock.writeLock().unlock(); } void read() { //Если в каком то из потоков в этом объекте //случился writeLock().lock() и пока еще не случился //writeLock().unlock() то readLock().lock() //останавливает потоки, которые дошли //до readLock().lock() в этом объекте ресурса. lock.readLock().lock(); System.out.println("Counter: " + value); lock.readLock().unlock(); } } static class CountThread implements Runnable { CommonResource res; CountThread(CommonResource res){ this.res=res; } public void run(){ for (int i = 0; i < 5; i++) { try { Thread.sleep(200); } catch(InterruptedException e){} //Пока объект заблокирован записью //чтение потоками не будет происходить. res.read(); } } } }

Вывод:

Из консоли видно, что три запущенных в мейн потока каждый раз ждут пока мейн запишет 10 миллиардов в переменную value в ресурсе, и каждый раз, как он это сделал потоки выводят переменную value с добавленными 10 миллиардами.

ThreadLocal в Java: переменные потока

ThreadLocal в Java: создавайте потокобезопасные переменные, уникальные для каждого потока. Пример использования и работа с потоконебезопасными объектами.
Time to read: 16

Fork/Join framework в Java

Fork/Join Framework в Java: разбивайте задачи на подзадачи для параллельного выполнения. Пример использования RecursiveTask и оптимизация многопоточных вычислений.
Time to read: 18

Что такое сериализация в Java

Узнайте, как работает сериализация в Java: сохраняйте объекты в файлы с ObjectOutputStream и восстанавливайте их через ObjectInputStream. Пример кода и важность интерфейса Serializable.
Time to read: 10