1.实现一个读写缓存的操作,假设开始没有加锁的时候,会出现什么情况

复制代码
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

class MyCache {

    private volatile Map<String, Object> map = new HashMap<>();

    public void put(String key, Object value) {
        System.out.println(Thread.currentThread().getName() + "\t 正在写入:" + key);
        try {
            // 模拟网络拥堵,延迟0.3秒
            TimeUnit.MILLISECONDS.sleep(300);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        map.put(key, value);
        System.out.println(Thread.currentThread().getName() + "\t 写入完成");
    }

    public void get(String key) {
        System.out.println(Thread.currentThread().getName() + "\t 正在读取:");
        try {
            // 模拟网络拥堵,延迟0.3秒
            TimeUnit.MILLISECONDS.sleep(300);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        Object value = map.get(key);
        System.out.println(Thread.currentThread().getName() + "\t 读取完成:" + value);
    }
}

public class ReadWriteWithoutLockDemo {

    public static void main(String[] args) {
        MyCache myCache = new MyCache();
        // 线程操作资源类,5个线程写
        for (int i = 0; i < 5; i++) {
            final int tempInt = i;
            new Thread(() -> {
                myCache.put(tempInt + "", tempInt +  "");
            }, String.valueOf(i)).start();
        }
        
        // 线程操作资源类, 5个线程读
        for (int i = 0; i < 5; i++) {
            final int tempInt = i;
            new Thread(() -> {
                myCache.get(tempInt + "");
            }, String.valueOf(i)).start();
        }

    }

}
复制代码

2.执行结果

复制代码
0     正在写入:0
1     正在写入:1
3     正在写入:3
2     正在写入:2
4     正在写入:4
0     正在读取:
1     正在读取:
2     正在读取:
4     正在读取:
3     正在读取:
1     写入完成
4     写入完成
0     写入完成
2     写入完成
3     写入完成
3     读取完成:3
0     读取完成:0
2     读取完成:2
1     读取完成:null
4     读取完成:null
复制代码

3.看到有些线程读取到null,可用ReentrantReadWriteLock解决

复制代码
package com.mydemo;

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

public class ReadWriteWithoutLockDemo {
    public static void main(String[] args) {
        MyCache myCache = new MyCache();
        for (int i = 0; i < 5; i++) {
            final int i1=i;
            new Thread(()->{
                myCache.put(i1+"",i1+"");
            },String.valueOf(i)).start();
        }

        for (int i = 0; i < 5; i++) {
            final int i1=i;
            new Thread(()->{
                myCache.get(i1+"");
            },String.valueOf(i)).start();
        }

    }
}


class MyCache{
    private  volatile HashMap<String,String> map=new HashMap<>();
    ReentrantReadWriteLock readWriteLock=new ReentrantReadWriteLock();
    public void put(String key,String value){
        readWriteLock.writeLock().lock();
        System.out.println(Thread.currentThread().getName()+"\t 正在写入"+key);
        try {
                        TimeUnit.SECONDS.sleep(1);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
        map.put(key,value);
        System.out.println(Thread.currentThread().getName()+"\t 写入完毕"+key);
        readWriteLock.writeLock().unlock();


    }
    public void get(String key){
        readWriteLock.readLock().lock();
        System.out.println(Thread.currentThread().getName()+"\t正在读取:");
        try {
                        TimeUnit.SECONDS.sleep(1);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
        String s = map.get(key);
        System.out.println(Thread.currentThread().getName()+"\t读取完"+s);
        readWriteLock.readLock().unlock();

    }


}
复制代码

4.执行结果

复制代码
1     正在写入1
1     写入完毕1
0     正在写入0
0     写入完毕0
2     正在写入2
2     写入完毕2
3     正在写入3
3     写入完毕3
4     正在写入4
4     写入完毕4
0    正在读取:
1    正在读取:
2    正在读取:
3    正在读取:
4    正在读取:
4    读取完4
3    读取完3
2    读取完2
1    读取完1
0    读取完0
复制代码

对ReentrantReadWriteLock其读锁是共享锁,其写锁是独占锁。

posted on   upupup-999  阅读(47)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?



点击右上角即可分享
微信分享提示