[097] 技术-java中的读写锁

2017-12-19  本文已影响0人  shawnxjf

读写所概念

我们平常通过锁来对进程进行协同。
但如果在读多写少的场景(可以允许多个读同时进行不影响)也使用普通的锁,会严重影响程序的性能。
为了解决这个问题引入读写锁,请看下面场景1:
1.读线程:如果thread在写resource的时候,其他read和write线程都终止。
2.写线程:可以允许多个thread同时读取resource。

我们先澄清一下定义和规则:
a.如果一个线程是读取资源就叫读线程,如果是写资源就叫写线程。
b.为了实现上面的“场景1”的要求,在代码中我们需要在读操作加上read锁,在写操作加上write锁。

读写所机制伪代码讲解

ReadWriteLock wrLock = new ReentrantReadWriteLock();

read线程执行获取读锁:

get(){
    wrlock.getReadLock.lock();
     ...println(Thread.currentThread().getName() + " 准备读数据!");  
            /* 休眠 */  
     ...println(Thread.currentThread().getName() + "读取完毕 :" + data);  
    wrlock.getReadLock.unlock();
}

write线程执行获取写锁:

put(){
    wrlock.getWriteLock.lock();
    ...println(Thread.currentThread().getName() + " 准备写入数据!");  
            /* 休眠 */  
     ...println(Thread.currentThread().getName() + "写入完毕");  
    wrlock.getWriteLock.unlock();
}

运行结果为:
/*******a b 两个线程同时执行*****/
a准备读取数据
b准备读取数据
a读取完毕
b读取完毕

/一次只有一个写线程,所以先c执行再d执行*/
// c线程执行
c准备写入数据!
c写入完毕
// d线程执行
d准备写入数据!
d写入完毕

如何使用

加锁是使其资源原子性,不管其资源是内存还是数据库。

我们并发控制的是资源不是代码?比如如下代码如何协同:
A: code1 code2
B: code1 code2

想象执行序列:
a).A,B线程都执行到code1 :A :code1 B:code1。
b).A执行到code1,B执行到code2。

不管执行序列如何,我们必须通过同一个lock对象来协同线程的访问。
在该排他代码的地方加 write锁,在非排他地方加read锁。

参考

http://tutorials.jenkov.com/java-concurrency/read-write-locks.html

上一篇 下一篇

猜你喜欢

热点阅读