学习过程观看视频:[狂神说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使用权,才开始执行。 读操作是任何线程都可以随时读的,所以,我们这边输出结果是随机的。