一、说明
- 1.当读操作远远高于写操作时,使用读写锁让读读可以并发,来提高性能
- 2.类似于数据库中的select … from … lock in share mode
- 3.提供一个数据容器类,内部分别使用读锁保护数据的read()方法,写锁保护数据的write()方法
二、读读不互斥
2.1 代码示例
package com.learning;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.locks.ReentrantReadWriteLock;
@Slf4j
public class ReadWriteLockLearning {
private Object data;
private ReentrantReadWriteLock reentrantReadWriteLock = new ReentrantReadWriteLock();
private ReentrantReadWriteLock.ReadLock readLock = reentrantReadWriteLock.readLock();
private ReentrantReadWriteLock.WriteLock writeLock = reentrantReadWriteLock.writeLock();
public Object read(){
log.debug("获取读锁");
readLock.lock();
try {
log.debug("读取");
try {
Thread.sleep(1000);
}catch(Exception e){
e.printStackTrace();
}
return data;
}finally {
log.debug("释放读锁");
readLock.unlock();
}
}
public void write(){
log.debug("获取写锁");
writeLock.lock();
try{
log.debug("写入");
}finally {
log.debug("释放写锁");
writeLock.unlock();
}
}
public static void main(String[] args) {
ReadWriteLockLearning readWriteLockLearning = new ReadWriteLockLearning();
new Thread(()->{
readWriteLockLearning.read();
}, "t1").start();
new Thread(()->{
readWriteLockLearning.read();
}, "t2").start();
}
}
2.2 截图示例
三、读写互斥
3.1 代码示例
package com.learning;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.locks.ReentrantReadWriteLock;
@Slf4j
public class ReadWriteLockLearning {
private Object data;
private ReentrantReadWriteLock reentrantReadWriteLock = new ReentrantReadWriteLock();
private ReentrantReadWriteLock.ReadLock readLock = reentrantReadWriteLock.readLock();
private ReentrantReadWriteLock.WriteLock writeLock = reentrantReadWriteLock.writeLock();
public Object read(){
log.debug("获取读锁");
readLock.lock();
try {
log.debug("读取");
return data;
}finally {
log.debug("释放读锁");
readLock.unlock();
}
}
public void write(){
log.debug("获取写锁");
writeLock.lock();
try{
log.debug("写入");
try {
Thread.sleep(1000);
}catch(Exception e){
e.printStackTrace();
}
}finally {
log.debug("释放写锁");
writeLock.unlock();
}
}
public static void main(String[] args) {
ReadWriteLockLearning readWriteLockLearning = new ReadWriteLockLearning();
new Thread(()->{
readWriteLockLearning.read();
}, "t1").start();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
new Thread(()->{
readWriteLockLearning.write();
}, "t2").start();
}
}
3.2 截图示例
四、写写互斥
4.1 代码示例
package com.learning;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.locks.ReentrantReadWriteLock;
@Slf4j
public class ReadWriteLockLearning {
private Object data;
private ReentrantReadWriteLock reentrantReadWriteLock = new ReentrantReadWriteLock();
private ReentrantReadWriteLock.ReadLock readLock = reentrantReadWriteLock.readLock();
private ReentrantReadWriteLock.WriteLock writeLock = reentrantReadWriteLock.writeLock();
public Object read(){
log.debug("获取读锁");
readLock.lock();
try {
log.debug("读取");
return data;
}finally {
log.debug("释放读锁");
readLock.unlock();
}
}
public void write(){
log.debug("获取写锁");
writeLock.lock();
try{
log.debug("写入");
try {
Thread.sleep(1000);
}catch(Exception e){
e.printStackTrace();
}
}finally {
log.debug("释放写锁");
writeLock.unlock();
}
}
public static void main(String[] args) {
ReadWriteLockLearning readWriteLockLearning = new ReadWriteLockLearning();
new Thread(()->{
readWriteLockLearning.write();
}, "t1").start();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
new Thread(()->{
readWriteLockLearning.write();
}, "t2").start();
}
}
4.2 截图示例
文章来源:https://www.toymoban.com/news/detail-684075.html
五、注意事项
- 1.读锁不支持条件变量
- 2.不支持重入时升级:持有读锁的情况下去获取写锁,会导致获取写锁永久等待
5.2.1 代码示例
package com.learning;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.locks.ReentrantReadWriteLock;
@Slf4j
public class ReadWriteLockLearning2 {
private Object data;
private ReentrantReadWriteLock reentrantReadWriteLock = new ReentrantReadWriteLock();
private ReentrantReadWriteLock.ReadLock readLock = reentrantReadWriteLock.readLock();
private ReentrantReadWriteLock.WriteLock writeLock = reentrantReadWriteLock.writeLock();
public void readWrite(){
log.debug("获取读锁");
readLock.lock();
try {
try{
log.debug("获取写锁");
writeLock.lock();
}finally {
log.debug("释放写锁");
writeLock.unlock();
}
}finally {
log.debug("释放读锁");
readLock.unlock();
}
}
public static void main(String[] args) {
ReadWriteLockLearning2 readWriteLockLearning = new ReadWriteLockLearning2();
readWriteLockLearning.readWrite();
}
}
5.2.2 截图示例
文章来源地址https://www.toymoban.com/news/detail-684075.html
- 3.支持重入时降级:持有写锁的情况下去获取读锁
到了这里,关于【juc】读写锁ReentrantReadWriteLock的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!