一、什么是读写锁

读写锁是JDK1.5提供的一个工具锁,适用于读多写少的场景,将读写分离,从而提高并发性。

二、读写锁的特点

读锁是共享锁,写锁是排他锁,读锁和写锁不能同时存在;

读锁不能升级为写锁;

写锁可以降级为读锁;

三、锁的本质

锁的本质就是锁住一块资源而不是一块代码. 在常见的一些代码实现都是加一把大锁,将这一块代码资源统一加锁,无法针对资源进行精确进行锁控制.

四、代码实现

`

import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.ConcurrentHashMap;

import java.util.concurrent.locks.ReadWriteLock;

import java.util.concurrent.locks.ReentrantReadWriteLock;

@Slf4j

public class UserDefinedLock {

final ConcurrentHashMap<String, ReadWriteLock> map = new ConcurrentHashMap<>();

public UserDefinedLock() {

}

/**
* 从map里获取锁 如果存在则返回 不存在则创建
*
* @param key key
* @return lock
*/
public void createOrGetLock(String key) {
synchronized (key.intern()) {
map.compute(key, (k, lock) -> {
if (lock == null) {
lock = new ReentrantReadWriteLock();
}
return lock;
});
}
} /**
* 获取锁 会阻塞
*
* @param key key
*/
public void writeLock(String key) {
map.get(key).writeLock().lock();
} public void readLock(String key) {
map.get(key).readLock().lock();
} /**
* 释放锁 必须由申请锁的线程进行调用
*
* @param key key
*/
public void unWriteLock(String key) {
ReadWriteLock lock = map.get(key);
if (null != lock) {
try {
lock.writeLock().unlock();
} catch (Exception e) {
log.error("释放写锁失败,key:{}, msg:{}", key, e.getMessage());
}
}
} public void unReadLock(String key) {
ReadWriteLock lock = map.get(key);
if (null != lock) {
try {
lock.readLock().unlock();
} catch (Exception e) {
log.error("释放读锁失败,key:{}, msg:{}", key, e.getMessage());
}
}
}
public static void main(String[] args) {
UserDefinedLock userDefinedLock = new UserDefinedLock();
ArrayList list = new ArrayList<String>();
for (int i = 0; i < 5; i++) {
String key = String.valueOf("测试" + i);
new Thread(() -> {
try {
userDefinedLock.createOrGetLock(key);
userDefinedLock.readLock(key);
System.out.println("-----" + key + "----");
list.add(key);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
userDefinedLock.unReadLock(key);
}
}, "read-" + key).start();
}
}

}

`

最新文章

  1. 还原后缀名为.bak的数据库备份文件
  2. 【XLL 框架库函数】 TempActiveRef/TempActiveRef12
  3. 从Jetty、Tomcat和Mina中提炼NIO构架网络服务器的经典模式(三)
  4. 大四找实习(web前端),加油
  5. What is martian source / martian packets
  6. 整理的Java资源
  7. mount CIFS return ERR -12 and report Cannot allocate memory
  8. [转]Android与电脑局域网共享之:Samba Client
  9. bzoj3064 Tyvj 1518 CPU监控
  10. 案例学习总结:原生JS实现表格排序
  11. 消息中间件kafka+zookeeper集群部署、测试与应用
  12. Azure基础(三)- Azure的物理架构和服务保证
  13. MemCache在网站中的使用
  14. PHP常见面试题汇总(二)
  15. HP Instant Information
  16. Java集合类源码解析:LinkedHashMap
  17. js实现svg图形转存为图片下载[转]
  18. 【BZOJ1951】古代猪文(CRT,卢卡斯定理)
  19. [Maven实战-许晓斌]-[第三章] Mave使用入门二(在IDE中的使用) [第四章] 案例的背景介绍
  20. MB Star C5 Functions

热门文章

  1. MATLAB实现随机森林(RF)回归与自变量影响程度分析
  2. Visual Studio增加Class类顶部签名描述信息
  3. Activiti-25张表对应的关系以及常用接口
  4. python压缩解压文件
  5. Git基础操作及协作流程
  6. 免杀之:C# XOR Shellcode
  7. Vulhub 漏洞学习之:Couchdb
  8. 基于C++的OpenGL 04 之变换
  9. Vue学习笔记之表单绑定
  10. word2021自带viso屏幕闪烁、抖动问题解决