ReentrantReadWriterLock初步了解
ReentrantReadWriter lock=new ReentrantReadWriter();
读锁建立:lock.readLock().lock(); 解除:lock.readLock().unlock();
写锁建立:lock.writeLock().lock(); 解除:lock.writeLock().unlock();
测试类:
//实体类
class LockQueue {
private Object data = null;
private ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
public void get() {
//上读锁
lock.readLock().lock();
System.out.println(Thread.currentThread().getName() + "准备好读取data");
try {
Thread.sleep((long) (Math.random() * 1000));
} catch (Exception e) {
e.printStackTrace();
} finally {
System.out.println(Thread.currentThread().getName() + "已经读取到了data");
lock.readLock().unlock();
}
}
public void put(Object data) {
//上写锁
lock.writeLock().lock();
System.out.println(Thread.currentThread().getName() + "准备好写data!");
try {
Thread.sleep((long) (Math.random() * 1000));
} catch (Exception e) {
e.printStackTrace();
} finally {
this.data = data;
System.out.println(Thread.currentThread().getName() + "已经写好了data!");
lock.writeLock().unlock();
}
}
}
用线程时候
/**
*@Author: wangshun
*@date: 2022/8/9 16:04
*@Description: 最后输出为:为正确的结果
*
* Thread-48准备好读取data
* Thread-47准备好读取data
* Thread-50准备好读取data
* Thread-49准备好读取data
* --------------------------- 这样的读锁是能够并行的,多线程并行
* Thread-47已经读取到了data
* Thread-48已经读取到了data
* Thread-49已经读取到了data
* Thread-50已经读取到了data
* ---------------------------
* Thread-51准备好写data!
* Thread-51已经写好了data!-----这样的写锁是不能并行的,只能等上一个线程结束才能执行下一个线程
*
* Thread-52准备好写data!
* Thread-52已经写好了data!
*
* Thread-53准备好写data!
* Thread-53已经写好了data!
*
* Thread-54准备好写data!
* Thread-54已经写好了data!
*
*@Version: 1.0
*/
@ApiOperation("测试锁2")
@PostMapping("/testLock2")
public void testLockNew() {
final LockQueue lock = new LockQueue();
for (int i = 0; i < 4; ++i) {
new Thread() {
@Override
public void run() {
//读锁测试
lock.get();
}
}.start();
}
for (int i = 0; i < 4; ++i) {
new Thread() {
@Override
public void run() {
//写锁测试
lock.put(new Random().nextInt(10000));
}
}.start();
}
}
不用线程时候
/**
*@Author: wangshun
*@date: 2022/8/9 16:06
*@Description:
*这里在上面的基础上进行修改,for循环中没用new Thread.start来启动,直接循环-->是有问题的
*最后输出的都是一个线程,不是多线程了,而是单线程的多次循环
*所以这里的读写锁不会起作用
*这里的执行顺序就是单线程一步一步顺序进行的
* http-nio-10003-exec-2准备好读取data
* http-nio-10003-exec-2已经读取到了data
* http-nio-10003-exec-2准备好读取data
* http-nio-10003-exec-2已经读取到了data
* http-nio-10003-exec-2准备好读取data
* http-nio-10003-exec-2已经读取到了data
* http-nio-10003-exec-2准备好读取data
* http-nio-10003-exec-2已经读取到了data
* http-nio-10003-exec-2准备好写data!
* http-nio-10003-exec-2已经写好了data!
* http-nio-10003-exec-2准备好写data!
* http-nio-10003-exec-2已经写好了data!
* http-nio-10003-exec-2准备好写data!
* http-nio-10003-exec-2已经写好了data!
* http-nio-10003-exec-2准备好写data!
* http-nio-10003-exec-2已经写好了data!
*@Version: 1.0
*/
@PostMapping("/testLock3")
@ApiOperation("读写锁测试3")
public void testLock3() {
StopWatch stopWatch = new StopWatch();
stopWatch.start();
LockQueue lockQueue = new LockQueue();
for (int i = 0; i < 4; i++) {
lockQueue.get();
}
for (int i = 0; i < 4; i++) {
lockQueue.put("你好");
}
stopWatch.stop();
System.out.println(stopWatch.prettyPrint());
}