第9章 读写锁

9.1.读写锁

 

1.读锁发生死锁的情况:线程1修改记录1,同时线程2在读取记录1;线程2修改记录1,同时线程1在读取记录1,

线程1需要等待线程2读完后释放锁才能修改,线程2也需要等待线程1读完后释放锁才能修改。互相持有对方所需的锁。

 

 

 2.写锁发生死锁的情况:线程1写操作记录1的同时操作记录2;线程2写操作记录2的同时操作记录1,

线程1需要等待线程2写完记录2才能操作,线程2需要等待线程1写完记录1才能操作。互相持有对方所需的锁。

 

复制代码
package JUC.readWrite;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

//资源类
class MyCache {

    //创建map集合
    private volatile Map<String,Object> map = new HashMap<>();

    //创建读写锁对象
    private ReadWriteLock readWriteLock = new ReentrantReadWriteLock();

    //放数据
    public void put(String key,Object value){
        //添加写锁
        readWriteLock.writeLock().lock();

        try {
            System.out.println(Thread.currentThread().getName()+" 正在写操作"+key);
            //暂停一会
            TimeUnit.MICROSECONDS.sleep(300);
            //放数据
            map.put(key,value);
            System.out.println(Thread.currentThread().getName()+" 写完了"+key);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            //释放锁
            readWriteLock.writeLock().unlock();
        }
    }

    //取数据
    public Object get(String key){
        //添加读锁
        readWriteLock.readLock().lock();
        Object result = null;
        try {
            System.out.println(Thread.currentThread().getName()+" 正在读取操作"+key);
            //暂停一会
            TimeUnit.MICROSECONDS.sleep(300);
            result = map.get(key);
            System.out.println(Thread.currentThread().getName()+" 取完了"+key);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            //释放锁
            readWriteLock.readLock().unlock();
        }

        return result;
    }

}

public class ReadWriteLockDemo {

    public static void main(String[] args) {
        MyCache myCache = new MyCache();
        //创建线程放数据
        for (int i = 1; i <= 5; i++) {
            final int num = i;
            new Thread(() -> {
                myCache.put(num+"",num+"");
            },String.valueOf(i)).start();
        }

        //创建线程取数据
        for (int i = 1; i <= 5; i++) {
            final int num = i;
            new Thread(() -> {
                myCache.get(num+"");
            },String.valueOf(i)).start();
        }

    }

}
复制代码

 

9.2 读写锁降级

 

 

复制代码
package JUC.readWrite;

import java.util.concurrent.locks.ReentrantReadWriteLock;

//演示读写锁降级
public class RWLockDemotionDemo {

    public static void main(String[] args) {
        //可重入读写锁对象
        ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock();
        ReentrantReadWriteLock.ReadLock readLock = rwLock.readLock();//读锁
        ReentrantReadWriteLock.WriteLock writeLock = rwLock.writeLock();//写锁

        //锁降级
        //1.获取写锁
        writeLock.lock();
        System.out.println("robert");

        //2.获取读锁
        readLock.lock();
        System.out.println("---read");

        //3.释放写锁
        writeLock.unlock();

        //4.释放读锁
        readLock.unlock();

    }

}
复制代码

 

posted @   狂热搬砖家  阅读(42)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· C# 集成 DeepSeek 模型实现 AI 私有化(本地部署与 API 调用教程)
· DeepSeek R1 简明指南:架构、训练、本地部署及硬件要求
· 没有源码,如何修改代码逻辑?
· NetPad:一个.NET开源、跨平台的C#编辑器
点击右上角即可分享
微信分享提示