读写锁特性:
多个线程的操作中,写写互斥、读写互斥、读读共享
新建一个ReetrantReadWriteLock的类,一个输出的方法,一个变量自增的方法,模拟三个线程,看输出结果:
package com.cljtest.demo.mylock;
public class ReentrantReadWriteLockDemo {
private int i = 0;
private int j = 0;
public void out(){
System.out.println(Thread.currentThread().getName()+"i的值为----->"+i+"--j的值为----->"+j);
}
public void inCreate(){
i++;
try {
Thread.sleep(1000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
j++;
}
public static void main(String[] args) {
ReentrantReadWriteLockDemo readWriteLockDemo = new ReentrantReadWriteLockDemo();
for(int i = 0;i<3;i++) {
new Thread(() -> {
readWriteLockDemo.inCreate();
readWriteLockDemo.out();
}).start();
}
}
}
运行结果为:
中间模拟了时间较长的操作,进行了sleep的休眠操作,运行结果发现,j的值不是我们想要的,首先进入increate方法,(可以将这个方法看成写的方法)先将i进行了变量增加的操作,然后执行了休眠,可能休眠还没结束,就已经开始了读的out()的方法,这个时候j的值还没有变化,所以才会造成i和j不是同步递增的结果。
可以考虑out()读的方法上加synchronized锁起来,也将写的increate()方法加上这个锁,这样就可以同步了,但是比较浪费资源,而且需要等待。这时就可以用读写锁ReadWriteLock进行操作:
private ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
Lock readLock = readWriteLock.readLock();
Lock writeLock = readWriteLock.writeLock();
用readLock.lock()在读的方法out()上加上锁,最后一定要注意写上finally进行锁的释放。
用writeLock.lock()对写的increate()方法加锁,同样最后要进行释放。
public void out(){
readLock.lock();
try {
System.out.println(Thread.currentThread().getName()+"i的值为----->"+i+"--j的值为----->"+j);
}catch (Exception e){
e.printStackTrace();
}finally {
//一定要注意手动释放锁
readLock.unlock();
}
}
public void inCreate(){
writeLock.lock();
try {
i++;
Thread.sleep(1000L);
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
writeLock.unlock();
}
j++;
}
运行,结果如下:
这样就达到了想要的i和j的值一致的结果了。
接下来来证明读写锁的特性:
1、写写互斥,模拟两个线程进行写的操作,debug验证:
new Thread(()->{
readWriteLockDemo.inCreate();
},"写线程1").start();
new Thread(()->{
readWriteLockDemo.inCreate();
},"写线程2").start();
}
主方法模拟两个写线程
debug走到还未释放锁的时候,切换写线程2
线程2尝试获取锁的时候进入了等待状态,这就证明了读写锁的写写互斥。
下面验证读写互斥:
new Thread(()->{
readWriteLockDemo.out();
},"读线程").start();
new Thread(()->{
readWriteLockDemo.inCreate();
},"写线程").start();
写线程先运行
读线程处于等待状态
证明读写互斥。
下面证明读读之间的共享:
读线程2是可以正常运行拿到锁的,所以读写锁中读读是可以共享的。
以上三个debug的模拟调试,证明了读写锁的特性:写写互斥、读写互斥和读读共享。
来源:CSDN
作者:jia718
链接:https://blog.csdn.net/jia718/article/details/103830911