一、什么是读写锁
读写锁是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();
- }
- }
复制代码 }
`
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |