pf711 2021-07-29 20:40 采纳率: 0%
浏览 24
已结题

Java 读写锁中 读锁未释放的情况下,竟然可以获取写锁

问题内容已经在程序运行结果中通过注释的方式提出来了

问题内容:
为什么在 线程pool-1-thread-2 还未释放 读锁 的时候,线程pool-1-thread-3 能获取到 写锁

代码如下:


import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

public class ReecentLock {

    private static ReecentLock instance = new ReecentLock();
    private Map<String,Object> map = new HashMap<>();
    private ReadWriteLock lock = new ReentrantReadWriteLock();

    public Object getData(String key) throws InterruptedException {
        lock.readLock().lock();
        Object value = null;
        System.out.println(Thread.currentThread().getName() + " 已经获取 读锁");
        try {
            value = map.get(key);
            if(value == null){
                System.out.println(Thread.currentThread().getName() + "准备释放读锁");
                lock.readLock().unlock();
                System.out.println(Thread.currentThread().getName() + "释放读锁");
                lock.writeLock().lock();

                System.out.println(Thread.currentThread().getName() + "已经获取 写锁");
                try {
                    value = map.get(key);
                    if(value == null){
                        System.out.println(Thread.currentThread().getName() + "----value----" + value);
                        value = "ddddd";
                        map.put(key,value);
                        System.out.println(Thread.currentThread().getName() +"设置缓存值");
                    }
                }finally {
                    lock.writeLock().unlock();
                    System.out.println(Thread.currentThread().getName() + "已经释放 写锁");
                }
                lock.readLock().lock();
                System.out.println(Thread.currentThread().getName() + "再次获取 读锁");
            }
        }finally {
            lock.readLock().unlock();
            System.out.println(Thread.currentThread().getName() + "再次释放 读锁");
        }
        System.out.println(value);
        return value;
    }

    private ReecentLock(){};

    public static ReecentLock getIntance(){
        return instance;
    }

    public static void main(String[] args) {
        ExecutorService executorService = Executors.newFixedThreadPool(3);
        for (int i=0;i<3;i++){
            executorService.execute(() -> {
                try {
                    ReecentLock.getIntance().getData("hello");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            });
        }
    }
}

运行结果如下:


pool-1-thread-2 已经获取 读锁
pool-1-thread-3 已经获取 读锁
pool-1-thread-1 已经获取 读锁
pool-1-thread-3准备释放读锁
pool-1-thread-2准备释放读锁
pool-1-thread-3释放读锁
pool-1-thread-1准备释放读锁
pool-1-thread-1释放读锁
pool-1-thread-3已经获取 写锁     //问题就在这里,这里已经获取到了写锁,可是,此时还有一个线程的读锁还没有释放
pool-1-thread-3----value----null
pool-1-thread-3设置缓存值
pool-1-thread-2释放读锁       //  这个线程的读锁还没释放
pool-1-thread-2已经获取 写锁
pool-1-thread-2已经释放 写锁
pool-1-thread-1已经获取 写锁
pool-1-thread-3已经释放 写锁
pool-1-thread-2再次获取 读锁
pool-1-thread-1已经释放 写锁
pool-1-thread-2再次释放 读锁
pool-1-thread-3再次获取 读锁
ddddd
pool-1-thread-1再次获取 读锁
pool-1-thread-3再次释放 读锁
ddddd
pool-1-thread-1再次释放 读锁
ddddd


  • 写回答

1条回答 默认 最新

  • pf711 2021-07-30 16:02
    关注

    恳请哪位大神看到能回答

    评论

报告相同问题?

问题事件

  • 系统已结题 8月6日
  • 修改了问题 7月30日
  • 创建了问题 7月29日

悬赏问题

  • ¥15 2020长安杯与连接网探
  • ¥15 关于#matlab#的问题:在模糊控制器中选出线路信息,在simulink中根据线路信息生成速度时间目标曲线(初速度为20m/s,15秒后减为0的速度时间图像)我想问线路信息是什么
  • ¥15 banner广告展示设置多少时间不怎么会消耗用户价值
  • ¥16 mybatis的代理对象无法通过@Autowired装填
  • ¥15 可见光定位matlab仿真
  • ¥15 arduino 四自由度机械臂
  • ¥15 wordpress 产品图片 GIF 没法显示
  • ¥15 求三国群英传pl国战时间的修改方法
  • ¥15 matlab代码代写,需写出详细代码,代价私
  • ¥15 ROS系统搭建请教(跨境电商用途)