Топ-100ReadWriteLock в Java - CodOrbits
LogoCodOrbits

Раздел: Многопоточность

В этом разделе вы узнаете, как использовать многопоточность в Java для повышения производительности и параллельной обработки.

Все разделы
Иконка Многопоточность

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
мин.

Similar Articles Icon
Divider

Fork/Join framework в Java

18
мин.

Similar Articles Icon
Divider

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

10
мин.

Similar Articles Icon