17、JUC:ReadWriteLock

学习过程观看视频:[狂神说Java]
https://www.bilibili.com/video/BV1B7411L7tE?p=13
欢迎大家支持噢,很良心的老师了!

前言:

我们自己定义一个缓存类,然后模拟并发写入,并发读取,看是否会存在并发问题。

package com.add;
import java.util.HashMap;
import java.util.Map;

/**
 * Created by zjl
 * 2020/11/24
 **/
public class ReadWriteLockDemo {
    
    

    public static void main(String[] args) {
    
    
        MyCache myCache = new MyCache();

        //写操作
        for (int i = 0; i < 5; i++) {
    
    
            final int temp = i;
            new Thread(()->{
    
    
                myCache.put(temp +"",temp+"");
            },String.valueOf(i)).start();
        }

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

/*
自定义缓存类
 */
class MyCache{
    
    

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

    //存值   写
    public void put(String key,Object value){
    
    
        System.out.println(Thread.currentThread().getName() + "开始写入");
        map.put(key,value);
        System.out.println(Thread.currentThread().getName() + "写入完毕!!!!!!");
    }

    //取值   读
    public void get(String key){
    
    
        System.out.println(Thread.currentThread().getName() + "开始读取");
        map.get(key);
        System.out.println(Thread.currentThread().getName() + "读取完毕--------");
    }
}

输出结果:

/Library/Java/JavaVirtualMachines/jdk1.8.0_231.jdk/Contents/Home/bin/java "-javaagent:/Users/zhangjianlong/Library/Application Support/JetBrains/Toolbox/apps/IDEA-U/ch-0/193.5662.53/IntelliJ IDEA.app/Contents/lib/idea_rt.jar=51602:/Users/zhangjianlong/Library/Application Support/JetBrains/Toolbox/apps/IDEA-U/ch-0/193.5662.53/IntelliJ IDEA.app/Contents/bin" -Dfile.encoding=UTF-8 -classpath /Library/Java/JavaVirtualMachines/jdk1.8.0_231.jdk/Contents/Home/jre/lib/charsets.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_231.jdk/Contents/Home/jre/lib/deploy.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_231.jdk/Contents/Home/jre/lib/ext/cldrdata.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_231.jdk/Contents/Home/jre/lib/ext/dnsns.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_231.jdk/Contents/Home/jre/lib/ext/jaccess.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_231.jdk/Contents/Home/jre/lib/ext/jfxrt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_231.jdk/Contents/Home/jre/lib/ext/localedata.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_231.jdk/Contents/Home/jre/lib/ext/nashorn.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_231.jdk/Contents/Home/jre/lib/ext/sunec.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_231.jdk/Contents/Home/jre/lib/ext/sunjce_provider.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_231.jdk/Contents/Home/jre/lib/ext/sunpkcs11.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_231.jdk/Contents/Home/jre/lib/ext/zipfs.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_231.jdk/Contents/Home/jre/lib/javaws.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_231.jdk/Contents/Home/jre/lib/jce.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_231.jdk/Contents/Home/jre/lib/jfr.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_231.jdk/Contents/Home/jre/lib/jfxswt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_231.jdk/Contents/Home/jre/lib/jsse.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_231.jdk/Contents/Home/jre/lib/management-agent.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_231.jdk/Contents/Home/jre/lib/plugin.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_231.jdk/Contents/Home/jre/lib/resources.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_231.jdk/Contents/Home/jre/lib/rt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_231.jdk/Contents/Home/lib/ant-javafx.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_231.jdk/Contents/Home/lib/dt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_231.jdk/Contents/Home/lib/javafx-mx.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_231.jdk/Contents/Home/lib/jconsole.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_231.jdk/Contents/Home/lib/packager.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_231.jdk/Contents/Home/lib/sa-jdi.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_231.jdk/Contents/Home/lib/tools.jar:/Users/zhangjianlong/testCode/JUC-study/target/classes:/Users/zhangjianlong/apache-maven-3.6.3/repository/org/projectlombok/lombok/1.18.8/lombok-1.18.8.jar com.add.ReadWriteLockDemo
0开始写入
4开始写入
4写入完毕!!!!!!
3开始写入
2开始写入
2写入完毕!!!!!!
1开始写入
3写入完毕!!!!!!
0写入完毕!!!!!!
1写入完毕!!!!!!
0开始读取
0读取完毕--------
1开始读取
1读取完毕--------
2开始读取
2读取完毕--------
3开始读取
3读取完毕--------
4开始读取
4读取完毕--------

Process finished with exit code 0

分析结果

我们可以看到,0开始写入,后面应该输出,0写入完毕!!!!!!,因为写的过程中,我们不希望其他线程影响,所以并没有达到我们的预期值。

我们使用ReadWriteLock后的效果

package com.add;
import jdk.nashorn.internal.ir.CallNode;

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

/**
 * Created by zjl
 * 2020/11/24
 **/
public class ReadWriteLockDemo {
    
    

    public static void main(String[] args) {
    
    
        MyCacheLock myCache = new MyCacheLock();

        //写操作
        for (int i = 0; i < 5; i++) {
    
    
            final int temp = i;
            new Thread(()->{
    
    
                myCache.put(temp +"",temp+"");
            },String.valueOf(i)).start();
        }

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

class MyCacheLock{
    
    

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

    //存值   写  写入的时候,只希望有一个线程写
    public void put(String key,Object value){
    
    
        readWriteLock.writeLock().lock();
        try {
    
    
            System.out.println(Thread.currentThread().getName() + "开始写入");
            map.put(key,value);
            System.out.println(Thread.currentThread().getName() + "写入完毕!!!!!!");
        } catch (Exception e) {
    
    
            e.printStackTrace();
        } finally {
    
    
            readWriteLock.writeLock().unlock();
        }
    }

    //取值   读   所有线程可以读
    public void get(String key){
    
    
        readWriteLock.readLock().lock();
        try {
    
    
            System.out.println(Thread.currentThread().getName() + "开始读取");
            map.get(key);
            System.out.println(Thread.currentThread().getName() + "读取完毕--------");
        } catch (Exception e) {
    
    
            e.printStackTrace();
        } finally {
    
    
            readWriteLock.readLock().unlock();
        }
    }
}

输出结果:

/Library/Java/JavaVirtualMachines/jdk1.8.0_231.jdk/Contents/Home/bin/java "-javaagent:/Users/zhangjianlong/Library/Application Support/JetBrains/Toolbox/apps/IDEA-U/ch-0/193.5662.53/IntelliJ IDEA.app/Contents/lib/idea_rt.jar=52302:/Users/zhangjianlong/Library/Application Support/JetBrains/Toolbox/apps/IDEA-U/ch-0/193.5662.53/IntelliJ IDEA.app/Contents/bin" -Dfile.encoding=UTF-8 -classpath /Library/Java/JavaVirtualMachines/jdk1.8.0_231.jdk/Contents/Home/jre/lib/charsets.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_231.jdk/Contents/Home/jre/lib/deploy.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_231.jdk/Contents/Home/jre/lib/ext/cldrdata.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_231.jdk/Contents/Home/jre/lib/ext/dnsns.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_231.jdk/Contents/Home/jre/lib/ext/jaccess.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_231.jdk/Contents/Home/jre/lib/ext/jfxrt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_231.jdk/Contents/Home/jre/lib/ext/localedata.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_231.jdk/Contents/Home/jre/lib/ext/nashorn.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_231.jdk/Contents/Home/jre/lib/ext/sunec.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_231.jdk/Contents/Home/jre/lib/ext/sunjce_provider.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_231.jdk/Contents/Home/jre/lib/ext/sunpkcs11.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_231.jdk/Contents/Home/jre/lib/ext/zipfs.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_231.jdk/Contents/Home/jre/lib/javaws.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_231.jdk/Contents/Home/jre/lib/jce.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_231.jdk/Contents/Home/jre/lib/jfr.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_231.jdk/Contents/Home/jre/lib/jfxswt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_231.jdk/Contents/Home/jre/lib/jsse.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_231.jdk/Contents/Home/jre/lib/management-agent.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_231.jdk/Contents/Home/jre/lib/plugin.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_231.jdk/Contents/Home/jre/lib/resources.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_231.jdk/Contents/Home/jre/lib/rt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_231.jdk/Contents/Home/lib/ant-javafx.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_231.jdk/Contents/Home/lib/dt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_231.jdk/Contents/Home/lib/javafx-mx.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_231.jdk/Contents/Home/lib/jconsole.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_231.jdk/Contents/Home/lib/packager.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_231.jdk/Contents/Home/lib/sa-jdi.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_231.jdk/Contents/Home/lib/tools.jar:/Users/zhangjianlong/testCode/JUC-study/target/classes:/Users/zhangjianlong/apache-maven-3.6.3/repository/org/projectlombok/lombok/1.18.8/lombok-1.18.8.jar com.add.ReadWriteLockDemo
0开始写入
0写入完毕!!!!!!
1开始写入
1写入完毕!!!!!!
2开始写入
2写入完毕!!!!!!
3开始写入
3写入完毕!!!!!!
4开始写入
4写入完毕!!!!!!
1开始读取
1读取完毕--------
0开始读取
2开始读取
2读取完毕--------
3开始读取
3读取完毕--------
4开始读取
4读取完毕--------
0读取完毕--------

Process finished with exit code 0

分析结果:

当一个线程在写的时候,其他线程不会影响当前线程,只有当前线程执行完毕了,其他线程才开始获得cpu使用权,才开始执行。 读操作是任何线程都可以随时读的,所以,我们这边输出结果是随机的。

猜你喜欢

转载自blog.csdn.net/qq_41347385/article/details/110088770
JUC