文章目录
1 场景引入
在多线程的情况下访问共享资源,需要对资源进行同步操作以防止数据不一致的情况发生,通常我们可以使用synchronized关键字或者显式锁。
对资源的访问一般包括两种类型的动作——读和写(更新、删除、增加等资源会发生变化的动作),如果多个线程在某个时刻都在进行资源的读操作,虽然有资源的竞争,但是这种竞争不足以引起数据不一致的情况发生,那么这个时候直接采用排他的方式加锁,就显得有些简单粗暴了。
**其实多线程在同一时间都进行读操作时不会引起冲突之外,其余的情况都会导致访问的冲突,需要对资源进行同步处理。**比如说两个线程同时对数据读取,是不会引起冲突,但是如果一个都在写或者一个读取,一个写入就会引起冲突。
如果对某个资源读的操作明显多过于写的操作,那么多线程读时并不加锁,很明显对程序性能的提升会有很大的帮助
所以多线程下,如果读写分离,则可以提高效率,读数据是的是可以并行的,只有写的时候加锁串行
我们更多需求更多的时候就是读取的时候,允许多个线程去读取,但是在写如数据的时候,只能有一个线程去写入,其他线程不能进行读取和写入
2 简单实现
简单实现,简单了解一下读写锁的设计原理
根据上面的分析:
- 多个线程读取数据是可以并行的,也就是说允许多个线程读取数据
- 写数据的时候,只能允许一个线程在写数据,其他线程不能读也不能写
所以定义锁的时候,设计了一下几个变量:
/**
* @Description: 当前正在读取数据线程数量
*/
private int readingThreads = 0;
/**
* @Description: 等待去读取数据的线程的数量, 但是读取不了,放到了wait队列中
*/
private int waitReadThreads = 0;
/**
* @Description: 正在写入数据的线程数量 只有一个
*/
private int writingThreads = 0;
/**
* @Description: 记录当前有多少个线程想要写入,但是写入不了,放到了wait队列中,在等待其他释放锁
*/
private int waitWriteThreads = 0;
public class ReadWriteLock {
/**
* @Description: 当前正在读取数据线程数量
*/
private int readingThreads = 0;
/**
* @Description: 等待去读取数据的线程的数量, 但是读取不了,放到了wait队列中
*/
private int waitReadThreads = 0;
/**
* @Description: 正在写入数据的线程数量 只能有一个
*/
private int writingThreads = 0;
/**
* @Description: 记录当前有多少个线程想要写入,但是写入不了,放到了wait队列中,在等待其他释放锁
*/
private int waitWriteThreads = 0;
/**
* 加读锁
*/
public synchronized void readLock() throws InterruptedException {
// 获取锁的时候,有可能获取不到锁,进入到等待队列(waitSet)中, 所以waitReadThreads可能需要加1的
this.waitReadThreads++;
try {
while (this.writingThreads > 0){
// 此时有线程正在写数据,便需要等待不能进行读取数据
// 不能在++,需要立刻等待,就放到外面,但是可能会记录的数量不对
// this.waitReadThreads++;
this.wait();
}
// 当前没有线程在写入数据,那么就可以读取数据
this.readingThreads++; // 正在读取数据的线程数量++
}finally {
// 当释放掉锁的时候,waitReadThreads --
this.waitReadThreads--;
}
}
/**
* 释放掉读锁
*/
public synchronized void unReadLock(){
// 当前正在读取数据线程数量 --
this.readingThreads--;
// 唤醒其他线程
this.notifyAll();
}
/**
* 加写锁
*/
public synchronized void writeLock() throws InterruptedException {
// 获取锁的时候,有可能获取不到锁,进入到等待队列(waitSet)中, 所以waitWriteThreads可能需要加1的
this.waitWriteThreads++;
try {
while (this.writingThreads > 0 || this.readingThreads > 0){
// 当有其他线程正在读取数据和写入数据的时候,此时不能写入数据,需要等待
// this.waitWriteThreads++; // 同样也不能再这样++
this.wait();
}
// 当前其他线程正在读取数据和写入数据的时候, 就可以写入数据了
this.writingThreads++;

最低0.47元/天 解锁文章
564

被折叠的 条评论
为什么被折叠?



