Java多线程 ReadWriteLock 实现读者写者问题

Thalia ·
更新时间:2024-09-20
· 526 次阅读

Java多线程 ReadWriteLock读写锁的使用 文章目录Java多线程 ReadWriteLock读写锁的使用1、ReadWriteLock 简介2、实例:读者写者问题3、总结 1、ReadWriteLock 简介

(1)ReadWriteLock接口的实现类-ReentrantReadWriteLock读写锁两个锁,一个是读操作相关的锁也成为共享锁,一个是写操作相关的锁 也称为排他锁。通过分离读锁和写锁,其并发性比一般排他锁有了很大提升。

锁的特点:
1、多个读锁之间不互斥,
2、读锁与写锁互斥,
3、写锁与写锁互斥(只要出现写操作的过程就是互斥的。)

在没有线程Thread进行写入操作时,进行读取操作的多个Thread都可以获取读锁,而进行写入操作的Thread只有在获取写锁后才能进行写入操作。即多个Thread可以同时进行读取操作,但是同一时刻只允许一个Thread进行写入操作。

(2)ReentrantReadWriteLock的特性

特性 说明
可重入性 该锁支持可重入,以读写线程为例:读线程在获取了读锁之后,能够再次获取读锁。而写线程在获取了写锁之后能够再次获取写锁也能够同时获取读锁
锁降级 写锁能够降级称为读锁,并遵循获取写锁、获取读锁再释放写锁的次序
公平性选择 支持非公平(默认)和公平的锁获取方式,吞吐量上来看还是非公平优于公平

(3)ReentrantReadWriteLock常见构造方法

ReentrantReadWriteLock(): 创建一个 ReentrantReadWriteLock()的实例

ReentrantReadWriteLock(boolean fair) :创建一个特定锁类型(公平锁/非公平锁)的ReentrantReadWriteLock的实例

2、实例:读者写者问题

读者—写者问题(Readers-Writers problem)也是一个经典的并发程序设计问题,是经常出现的一种同步问题。计算机系统中的数据(文件、记录)常被多个进程共享,但其中某些进程可能只要求读数据(称为读者Reader);另一些进程则要求修改数据(称为写者Writer)。就共享数据而言,Reader和Writer是两组并发进程共享一组数据区,要求:

(1)允许多个读者同时执行读操作;

(2)不允许读者、写者同时操作;

(3)不允许多个写者同时操作。

下面是ReentrantReadWriteLock的代码实现:

package chat7; import java.util.Random; import java.util.concurrent.locks.ReentrantReadWriteLock; public class ReadWriteLockTest { //内部类 class DataBase { private Object data = null;// 共享数据,只能有一个线程能写该数据,但可以有多个线程同时读该数据。 private ReentrantReadWriteLock rwl = new ReentrantReadWriteLock(false); public void get() { rwl.readLock().lock();// 上读锁,其他线程只能读不能写 System.out.println("线程:" + Thread.currentThread().getName() + " 正在准备读取数据"); try { Thread.sleep((long) (Math.random() * 1000)); System.out.println(Thread.currentThread().getName() + "读到的数据为:" + data); } catch (InterruptedException e) { e.printStackTrace(); }finally { rwl.readLock().unlock(); // 释放读锁 } } public void put(Object data) { rwl.writeLock().lock();// 上写锁,不允许其他线程读也不允许写 System.out.println(Thread.currentThread().getName() + " 正准备写进数据"); this.data = data; System.out.println(Thread.currentThread().getName() + " 已经写进数据 " + data); try { Thread.sleep((long) (Math.random() * 1000)); } catch (InterruptedException e) { e.printStackTrace(); }finally { rwl.writeLock().unlock();// 释放写锁 } } public static void main(String[] args) { final DataBase q = new DataBase(); for (int i = 0; i < 2; i++) { //创建两个读者线程 new Thread() { public void run() { while (true) { q.get(); } } }.start(); } for (int i = 0; i < 2; i++) { //创建两个写者进程 new Thread() { public void run() { while (true) { q.put(new Random().nextInt(10000)); } } }.start(); } } } }

在这里插入图片描述

3、总结

(1)ReentrantReadWriteLock的拥有三大特性:
可重入性,降级锁,公平性选择;
(2)锁的三大特点:
1、多个读锁之间不互斥,
2、读锁与写锁互斥,
3、写锁与写锁互斥(只要出现写操作的过程就是互斥的。)


作者:仙辉



java多线程 JAVA 线程

需要 登录 后方可回复, 如果你还没有账号请 注册新账号