ReadWriteLock в Java
Last updated: 7 мая 2025 г.ReadWriteLock
– класс содержащий 2 лока: один для чтения, другой для записи.
Часто бывает так, что один поток пишет в ресурс, а много других потоков читают из него.
То есть один поток блокирует ресурс для записи, а другие потоки, желающие читать из ресурса, ждут пока он запишет, и после того, как записывающий закончил запись, потоки читают, и далее всё повторяется.
Пример программы:
1import java.io.*;
2import java.util.*;
3import java.util.concurrent.locks.ReadWriteLock;
4import java.util.concurrent.locks.ReentrantReadWriteLock;
5
6public class RedWrtLockExample {
7 static long numOfOperations=10000000000L;
8 public static void main(String[] args) {
9 CommonResource commonResource = new CommonResource(); //объект ресурса
10 for (int i = 1; i < 4; i++){
11 //Запускаем 3 потока и передаем в каждый из них
12 //ресурс общий для потоков.
13 Thread t =
14 new Thread(new CountThread(commonResource));
15 t.setName("Thread " + i);
16 t.start();
17 }
18 //5 раз записать 10 млрд в commonResource.value
19 for (int i = 0; i < 5; i++) {
20 //Здесь начинается запись в ресурс потоком мейн
21 //и пока происходит запись в ресурс потоком мейн
22 //другие потоки читать из ресурса не смогут.
23 commonResource.write();
24 try{
25 Thread.sleep(100);
26 }
27 catch(InterruptedException e){}
28 }
29 }
30 static class CommonResource {
31 long value;
32 private final ReadWriteLock lock =
33 new ReentrantReadWriteLock();
34 void write() {
35 //здесь происходит writeLock().lock() на время
36 //записи десяти млрд блокируем все другие потоки,
37 //которые дошли до readLock().lock() в этом объекте
38 lock.writeLock().lock();
39 for (long i = 0; i < numOfOperations; i++){
40 value++;
41 }
42 //запускаются залоченные в read
43 lock.writeLock().unlock();
44 }
45 void read() {
46 //Если в каком то из потоков в этом объекте
47 //случился writeLock().lock() и пока еще не случился
48 //writeLock().unlock() то readLock().lock()
49 //останавливает потоки, которые дошли
50 //до readLock().lock() в этом объекте ресурса.
51 lock.readLock().lock();
52 System.out.println("Counter: " + value);
53 lock.readLock().unlock();
54 }
55 }
56 static class CountThread implements Runnable {
57 CommonResource res;
58 CountThread(CommonResource res){
59 this.res=res;
60 }
61 public void run(){
62 for (int i = 0; i < 5; i++) {
63 try {
64 Thread.sleep(200);
65 }
66 catch(InterruptedException e){}
67 //Пока объект заблокирован записью
68 //чтение потоками не будет происходить.
69 res.read();
70 }
71 }
72 }
73}
Вывод:

Из консоли видно, что три запущенных в мейн потока каждый раз ждут пока мейн запишет 10 миллиардов в переменную value в ресурсе, и каждый раз, как он это сделал потоки выводят переменную value с добавленными 10 миллиардами.
Следующие уроки
ThreadLocal в Java: переменные потока
16
мин.
Fork/Join framework в Java
18
мин.
Что такое сериализация в Java
10
мин.