现象:一个线程修改了共享变量的值,另一个线程却不可见。(没有可见性修饰符也没有同步措施)
下面看一个示例:
缓存类
public class MyCache {
public String key;
public String value;
/**
* 标记cache是否为空
*/
public boolean isEmpty = true;
@Override
public String toString() {
return "MyCache{" +
"key='" + key + '\'' +
", value='" + value + '\'' +
", isEmpty=" + isEmpty +
'}';
}
}
写线程
/**
* 写线程
*/
public class InputThread extends Thread {
private int count = 0;
private int nums = 0;
private MyCache myCache;
/**
* 初始化缓存
*/
public InputThread(MyCache myCache) {
this.myCache = myCache;
}
/**
* 任务
*/
@Override
public void run() {
/**
* 往cache写入内容
* 0: 写入用户名
* 1: 写入密码
*/
while (true) {
if (myCache.isEmpty) {
nums=nums+1;
if (count == 0) {
myCache.key = "username";
myCache.value = "用户名";
} else {
myCache.key = "password";
myCache.value = "密码";
}
/**
* 0->1 1->0 0->1 1->0
* ...
*/
count = (count + 1) % 2;
//写入了内容,标记cache不为空
myCache.isEmpty = false;
System.out.println(nums+"[写]-----------------------------"+myCache);
}
}
}
}
读线程
/**
* 读线程
*/
public class OutputThread extends Thread {
private MyCache myCache;
private int num = 0;
/**
* 初始化缓存
*/
public OutputThread(MyCache myCache) {
this.myCache = myCache;
}
/**
* 任务
*/
@Override
public void run() {
/**
* 从cache读出内容
*/
while (true) {
if (!myCache.isEmpty) {
num=num+1;
System.out.println(num+"[读]" + myCache);
//读出了内容,标记cache为空
myCache.isEmpty = true;
}
}
}
}
测试类
public class Test {
public static void main(String[] args) {
//创建一个公共cache
MyCache myCache = new MyCache();
//创建写线程
InputThread inputThread = new InputThread(myCache);
//创建读线程
OutputThread outputThread = new OutputThread(myCache);
/**
* 启动基于同一个缓存的两个线程
* 写->读->写
* 打印内容:
* ...
* 240[读]MyCache{key='password', value='密码', isEmpty=false}
* 241[读]MyCache{key='username', value='用户名', isEmpty=false}
* 241[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
* 242[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
*
* 思考:执行的时候写线程明明写完了,也把标记值更新了,但是读线程那边出现阻塞了,什么情况?
* 分析:没有volatile修饰或synchronized加锁,共享变量在多线程(并行程序)中会出现可见性问题。也就是不能实现实时可见,但最终还是可见的。
* 这就是为什么明明写线程更新了值(还没有刷回内存),但是读线程依然拿了未更新的旧值,按道理不是应该阻塞一会吗,为什么一直阻塞呢?
* 现在的电脑一般都是多核CPU,有的处理器缓存的层级多,有的少,并且有的处理器可能有时候不会去同步主内存中最新的值,而一直从缓存获取值。
* 所以这就表现在程序中,刚开始,cpu调度的线程,会去主内存拿最新值,最后却不去拿了。
* 至此,又有疑问了,为什么最终会有cpu一直从缓存获取值呢?
* 这个我也不太确定,我觉的,可能是因为随着程序的运行,cpu的缓存越来越大,为了性能,最后处理器会直接从缓存中拿值。
* 解决多线程可见性问题:
* 1)使用volatile
* 2)使用synchronized
*/
inputThread.start();
outputThread.start();
}
}
打印内容:
D:\soft\java\jdk1.8\bin\java.exe "-javaagent:D:\soft\IntelliJ IDEA 2020.2.2\lib\idea_rt.jar=52202:D:\soft\IntelliJ IDEA 2020.2.2\bin" -Dfile.encoding=UTF-8 -classpath "D:\soft\java\jdk1.8\jre\lib\charsets.jar;D:\soft\java\jdk1.8\jre\lib\deploy.jar;D:\soft\java\jdk1.8\jre\lib\ext\access-bridge-64.jar;D:\soft\java\jdk1.8\jre\lib\ext\cldrdata.jar;D:\soft\java\jdk1.8\jre\lib\ext\dnsns.jar;D:\soft\java\jdk1.8\jre\lib\ext\jaccess.jar;D:\soft\java\jdk1.8\jre\lib\ext\jfxrt.jar;D:\soft\java\jdk1.8\jre\lib\ext\localedata.jar;D:\soft\java\jdk1.8\jre\lib\ext\nashorn.jar;D:\soft\java\jdk1.8\jre\lib\ext\sunec.jar;D:\soft\java\jdk1.8\jre\lib\ext\sunjce_provider.jar;D:\soft\java\jdk1.8\jre\lib\ext\sunmscapi.jar;D:\soft\java\jdk1.8\jre\lib\ext\sunpkcs11.jar;D:\soft\java\jdk1.8\jre\lib\ext\zipfs.jar;D:\soft\java\jdk1.8\jre\lib\javaws.jar;D:\soft\java\jdk1.8\jre\lib\jce.jar;D:\soft\java\jdk1.8\jre\lib\jfr.jar;D:\soft\java\jdk1.8\jre\lib\jfxswt.jar;D:\soft\java\jdk1.8\jre\lib\jsse.jar;D:\soft\java\jdk1.8\jre\lib\management-agent.jar;D:\soft\java\jdk1.8\jre\lib\plugin.jar;D:\soft\java\jdk1.8\jre\lib\resources.jar;D:\soft\java\jdk1.8\jre\lib\rt.jar;D:\idea working\springboot-mongo\target\classes;E:\maven\LocalWarehouse3\org\springframework\boot\spring-boot-starter\2.4.0\spring-boot-starter-2.4.0.jar;E:\maven\LocalWarehouse3\org\springframework\boot\spring-boot\2.4.0\spring-boot-2.4.0.jar;E:\maven\LocalWarehouse3\org\springframework\spring-context\5.3.1\spring-context-5.3.1.jar;E:\maven\LocalWarehouse3\org\springframework\boot\spring-boot-autoconfigure\2.4.0\spring-boot-autoconfigure-2.4.0.jar;E:\maven\LocalWarehouse3\org\springframework\boot\spring-boot-starter-logging\2.4.0\spring-boot-starter-logging-2.4.0.jar;E:\maven\LocalWarehouse3\ch\qos\logback\logback-classic\1.2.3\logback-classic-1.2.3.jar;E:\maven\LocalWarehouse3\ch\qos\logback\logback-core\1.2.3\logback-core-1.2.3.jar;E:\maven\LocalWarehouse3\org\apache\logging\log4j\log4j-to-slf4j\2.13.3\log4j-to-slf4j-2.13.3.jar;E:\maven\LocalWarehouse3\org\apache\logging\log4j\log4j-api\2.13.3\log4j-api-2.13.3.jar;E:\maven\LocalWarehouse3\org\slf4j\jul-to-slf4j\1.7.30\jul-to-slf4j-1.7.30.jar;E:\maven\LocalWarehouse3\jakarta\annotation\jakarta.annotation-api\1.3.5\jakarta.annotation-api-1.3.5.jar;E:\maven\LocalWarehouse3\org\springframework\spring-core\5.3.1\spring-core-5.3.1.jar;E:\maven\LocalWarehouse3\org\springframework\spring-jcl\5.3.1\spring-jcl-5.3.1.jar;E:\maven\LocalWarehouse3\org\yaml\snakeyaml\1.27\snakeyaml-1.27.jar;E:\maven\LocalWarehouse3\org\springframework\boot\spring-boot-starter-data-mongodb\2.4.0\spring-boot-starter-data-mongodb-2.4.0.jar;E:\maven\LocalWarehouse3\org\mongodb\mongodb-driver-sync\4.1.1\mongodb-driver-sync-4.1.1.jar;E:\maven\LocalWarehouse3\org\mongodb\bson\4.1.1\bson-4.1.1.jar;E:\maven\LocalWarehouse3\org\mongodb\mongodb-driver-core\4.1.1\mongodb-driver-core-4.1.1.jar;E:\maven\LocalWarehouse3\org\springframework\data\spring-data-mongodb\3.1.1\spring-data-mongodb-3.1.1.jar;E:\maven\LocalWarehouse3\org\springframework\spring-tx\5.3.1\spring-tx-5.3.1.jar;E:\maven\LocalWarehouse3\org\springframework\spring-beans\5.3.1\spring-beans-5.3.1.jar;E:\maven\LocalWarehouse3\org\springframework\spring-expression\5.3.1\spring-expression-5.3.1.jar;E:\maven\LocalWarehouse3\org\springframework\data\spring-data-commons\2.4.1\spring-data-commons-2.4.1.jar;E:\maven\LocalWarehouse3\org\springframework\boot\spring-boot-starter-web\2.4.0\spring-boot-starter-web-2.4.0.jar;E:\maven\LocalWarehouse3\org\springframework\boot\spring-boot-starter-json\2.4.0\spring-boot-starter-json-2.4.0.jar;E:\maven\LocalWarehouse3\com\fasterxml\jackson\core\jackson-databind\2.11.3\jackson-databind-2.11.3.jar;E:\maven\LocalWarehouse3\com\fasterxml\jackson\core\jackson-annotations\2.11.3\jackson-annotations-2.11.3.jar;E:\maven\LocalWarehouse3\com\fasterxml\jackson\core\jackson-core\2.11.3\jackson-core-2.11.3.jar;E:\maven\LocalWarehouse3\com\fasterxml\jackson\datatype\jackson-datatype-jdk8\2.11.3\jackson-datatype-jdk8-2.11.3.jar;E:\maven\LocalWarehouse3\com\fasterxml\jackson\datatype\jackson-datatype-jsr310\2.11.3\jackson-datatype-jsr310-2.11.3.jar;E:\maven\LocalWarehouse3\com\fasterxml\jackson\module\jackson-module-parameter-names\2.11.3\jackson-module-parameter-names-2.11.3.jar;E:\maven\LocalWarehouse3\org\springframework\boot\spring-boot-starter-tomcat\2.4.0\spring-boot-starter-tomcat-2.4.0.jar;E:\maven\LocalWarehouse3\org\apache\tomcat\embed\tomcat-embed-core\9.0.39\tomcat-embed-core-9.0.39.jar;E:\maven\LocalWarehouse3\org\glassfish\jakarta.el\3.0.3\jakarta.el-3.0.3.jar;E:\maven\LocalWarehouse3\org\apache\tomcat\embed\tomcat-embed-websocket\9.0.39\tomcat-embed-websocket-9.0.39.jar;E:\maven\LocalWarehouse3\org\springframework\spring-web\5.3.1\spring-web-5.3.1.jar;E:\maven\LocalWarehouse3\org\springframework\spring-webmvc\5.3.1\spring-webmvc-5.3.1.jar;E:\maven\LocalWarehouse3\org\springframework\spring-aop\5.3.1\spring-aop-5.3.1.jar;E:\maven\LocalWarehouse3\org\projectlombok\lombok\1.18.16\lombok-1.18.16.jar;E:\maven\LocalWarehouse3\org\apache\commons\commons-lang3\3.11\commons-lang3-3.11.jar;E:\maven\LocalWarehouse3\com\vaadin\external\google\android-json\0.0.20131108.vaadin1\android-json-0.0.20131108.vaadin1.jar;E:\maven\LocalWarehouse3\com\alibaba\fastjson\1.2.51\fastjson-1.2.51.jar;E:\maven\LocalWarehouse3\org\apache\kafka\kafka-clients\2.6.2\kafka-clients-2.6.2.jar;E:\maven\LocalWarehouse3\com\github\luben\zstd-jni\1.4.4-7\zstd-jni-1.4.4-7.jar;E:\maven\LocalWarehouse3\org\lz4\lz4-java\1.7.1\lz4-java-1.7.1.jar;E:\maven\LocalWarehouse3\org\xerial\snappy\snappy-java\1.1.7.3\snappy-java-1.1.7.3.jar;E:\maven\LocalWarehouse3\org\slf4j\slf4j-api\1.7.30\slf4j-api-1.7.30.jar" com.example.demo.threaddemo4.Test
1[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
1[读]MyCache{key='username', value='用户名', isEmpty=false}
2[读]MyCache{key='password', value='密码', isEmpty=false}
2[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
3[读]MyCache{key='username', value='用户名', isEmpty=false}
3[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
4[读]MyCache{key='password', value='密码', isEmpty=false}
4[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
5[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
5[读]MyCache{key='username', value='用户名', isEmpty=false}
6[读]MyCache{key='password', value='密码', isEmpty=false}
6[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
7[读]MyCache{key='username', value='用户名', isEmpty=false}
7[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
8[读]MyCache{key='password', value='密码', isEmpty=false}
8[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
9[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
9[读]MyCache{key='username', value='用户名', isEmpty=false}
10[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
10[读]MyCache{key='password', value='密码', isEmpty=false}
11[读]MyCache{key='username', value='用户名', isEmpty=false}
11[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
12[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
12[读]MyCache{key='password', value='密码', isEmpty=false}
13[读]MyCache{key='username', value='用户名', isEmpty=false}
13[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
14[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
14[读]MyCache{key='password', value='密码', isEmpty=false}
15[读]MyCache{key='username', value='用户名', isEmpty=false}
15[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
16[读]MyCache{key='password', value='密码', isEmpty=false}
16[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
17[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
17[读]MyCache{key='username', value='用户名', isEmpty=false}
18[读]MyCache{key='password', value='密码', isEmpty=false}
18[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
19[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
19[读]MyCache{key='username', value='用户名', isEmpty=false}
20[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
20[读]MyCache{key='password', value='密码', isEmpty=false}
21[读]MyCache{key='username', value='用户名', isEmpty=false}
21[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
22[读]MyCache{key='password', value='密码', isEmpty=false}
22[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
23[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
23[读]MyCache{key='username', value='用户名', isEmpty=false}
24[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
24[读]MyCache{key='password', value='密码', isEmpty=false}
25[读]MyCache{key='username', value='用户名', isEmpty=false}
25[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
26[读]MyCache{key='password', value='密码', isEmpty=false}
26[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
27[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
27[读]MyCache{key='username', value='用户名', isEmpty=false}
28[读]MyCache{key='password', value='密码', isEmpty=false}
28[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
29[读]MyCache{key='username', value='用户名', isEmpty=false}
29[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
30[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
30[读]MyCache{key='password', value='密码', isEmpty=false}
31[读]MyCache{key='username', value='用户名', isEmpty=false}
31[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
32[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
32[读]MyCache{key='password', value='密码', isEmpty=false}
33[读]MyCache{key='username', value='用户名', isEmpty=false}
33[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
34[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
34[读]MyCache{key='password', value='密码', isEmpty=false}
35[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
35[读]MyCache{key='username', value='用户名', isEmpty=false}
36[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
36[读]MyCache{key='password', value='密码', isEmpty=false}
37[读]MyCache{key='username', value='用户名', isEmpty=false}
37[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
38[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
38[读]MyCache{key='password', value='密码', isEmpty=false}
39[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
39[读]MyCache{key='username', value='用户名', isEmpty=false}
40[读]MyCache{key='password', value='密码', isEmpty=false}
40[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
41[读]MyCache{key='username', value='用户名', isEmpty=false}
41[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
42[读]MyCache{key='password', value='密码', isEmpty=false}
42[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
43[读]MyCache{key='username', value='用户名', isEmpty=false}
43[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
44[读]MyCache{key='password', value='密码', isEmpty=false}
44[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
45[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
45[读]MyCache{key='username', value='用户名', isEmpty=false}
46[读]MyCache{key='password', value='密码', isEmpty=false}
46[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
47[读]MyCache{key='username', value='用户名', isEmpty=false}
47[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
48[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
48[读]MyCache{key='password', value='密码', isEmpty=false}
49[读]MyCache{key='username', value='用户名', isEmpty=false}
49[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
50[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
50[读]MyCache{key='password', value='密码', isEmpty=false}
51[读]MyCache{key='username', value='用户名', isEmpty=false}
51[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
52[读]MyCache{key='password', value='密码', isEmpty=false}
52[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
53[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
53[读]MyCache{key='username', value='用户名', isEmpty=false}
54[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
54[读]MyCache{key='password', value='密码', isEmpty=false}
55[读]MyCache{key='username', value='用户名', isEmpty=false}
55[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
56[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
56[读]MyCache{key='password', value='密码', isEmpty=false}
57[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
57[读]MyCache{key='username', value='用户名', isEmpty=false}
58[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
58[读]MyCache{key='password', value='密码', isEmpty=false}
59[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
59[读]MyCache{key='username', value='用户名', isEmpty=false}
60[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
60[读]MyCache{key='password', value='密码', isEmpty=false}
61[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
61[读]MyCache{key='username', value='用户名', isEmpty=false}
62[读]MyCache{key='password', value='密码', isEmpty=false}
62[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
63[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
63[读]MyCache{key='username', value='用户名', isEmpty=false}
64[读]MyCache{key='password', value='密码', isEmpty=false}
64[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
65[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
65[读]MyCache{key='username', value='用户名', isEmpty=false}
66[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
66[读]MyCache{key='password', value='密码', isEmpty=false}
67[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
67[读]MyCache{key='username', value='用户名', isEmpty=false}
68[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
68[读]MyCache{key='password', value='密码', isEmpty=false}
69[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
69[读]MyCache{key='username', value='用户名', isEmpty=false}
70[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
70[读]MyCache{key='password', value='密码', isEmpty=false}
71[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
71[读]MyCache{key='username', value='用户名', isEmpty=false}
72[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
72[读]MyCache{key='password', value='密码', isEmpty=false}
73[读]MyCache{key='username', value='用户名', isEmpty=false}
73[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
74[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
74[读]MyCache{key='password', value='密码', isEmpty=false}
75[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
75[读]MyCache{key='username', value='用户名', isEmpty=false}
76[读]MyCache{key='password', value='密码', isEmpty=false}
76[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
77[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
77[读]MyCache{key='username', value='用户名', isEmpty=false}
78[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
78[读]MyCache{key='password', value='密码', isEmpty=false}
79[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
79[读]MyCache{key='username', value='用户名', isEmpty=false}
80[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
80[读]MyCache{key='password', value='密码', isEmpty=false}
81[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
81[读]MyCache{key='username', value='用户名', isEmpty=false}
82[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
82[读]MyCache{key='password', value='密码', isEmpty=false}
83[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
83[读]MyCache{key='username', value='用户名', isEmpty=false}
84[读]MyCache{key='password', value='密码', isEmpty=false}
84[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
85[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
85[读]MyCache{key='username', value='用户名', isEmpty=false}
86[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
86[读]MyCache{key='password', value='密码', isEmpty=false}
87[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
87[读]MyCache{key='username', value='用户名', isEmpty=false}
88[读]MyCache{key='password', value='密码', isEmpty=false}
88[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
89[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
89[读]MyCache{key='username', value='用户名', isEmpty=false}
90[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
90[读]MyCache{key='password', value='密码', isEmpty=false}
91[读]MyCache{key='username', value='用户名', isEmpty=false}
91[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
92[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
92[读]MyCache{key='password', value='密码', isEmpty=false}
93[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
93[读]MyCache{key='username', value='用户名', isEmpty=false}
94[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
94[读]MyCache{key='password', value='密码', isEmpty=false}
95[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
95[读]MyCache{key='username', value='用户名', isEmpty=false}
96[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
96[读]MyCache{key='password', value='密码', isEmpty=false}
97[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
97[读]MyCache{key='username', value='用户名', isEmpty=false}
98[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
98[读]MyCache{key='password', value='密码', isEmpty=false}
99[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
99[读]MyCache{key='username', value='用户名', isEmpty=false}
100[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
100[读]MyCache{key='password', value='密码', isEmpty=false}
101[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
101[读]MyCache{key='username', value='用户名', isEmpty=false}
102[读]MyCache{key='password', value='密码', isEmpty=false}
102[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
103[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
103[读]MyCache{key='username', value='用户名', isEmpty=false}
104[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
104[读]MyCache{key='password', value='密码', isEmpty=false}
105[读]MyCache{key='username', value='用户名', isEmpty=false}
105[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
106[读]MyCache{key='password', value='密码', isEmpty=false}
106[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
107[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
107[读]MyCache{key='username', value='用户名', isEmpty=false}
108[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
108[读]MyCache{key='password', value='密码', isEmpty=false}
109[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
109[读]MyCache{key='username', value='用户名', isEmpty=false}
110[读]MyCache{key='password', value='密码', isEmpty=false}
110[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
111[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
111[读]MyCache{key='username', value='用户名', isEmpty=false}
112[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
112[读]MyCache{key='password', value='密码', isEmpty=false}
113[读]MyCache{key='username', value='用户名', isEmpty=false}
113[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
114[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
114[读]MyCache{key='password', value='密码', isEmpty=false}
115[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
115[读]MyCache{key='username', value='用户名', isEmpty=false}
116[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
116[读]MyCache{key='password', value='密码', isEmpty=false}
117[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
117[读]MyCache{key='username', value='用户名', isEmpty=false}
118[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
118[读]MyCache{key='password', value='密码', isEmpty=false}
119[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
119[读]MyCache{key='username', value='用户名', isEmpty=false}
120[读]MyCache{key='password', value='密码', isEmpty=false}
120[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
121[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
121[读]MyCache{key='username', value='用户名', isEmpty=false}
122[读]MyCache{key='password', value='密码', isEmpty=false}
122[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
123[读]MyCache{key='username', value='用户名', isEmpty=false}
123[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
124[读]MyCache{key='password', value='密码', isEmpty=false}
124[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
125[读]MyCache{key='username', value='用户名', isEmpty=false}
125[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
126[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
126[读]MyCache{key='password', value='密码', isEmpty=false}
127[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
127[读]MyCache{key='username', value='用户名', isEmpty=false}
128[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
128[读]MyCache{key='password', value='密码', isEmpty=false}
129[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
129[读]MyCache{key='username', value='用户名', isEmpty=false}
130[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
130[读]MyCache{key='password', value='密码', isEmpty=false}
131[读]MyCache{key='username', value='用户名', isEmpty=false}
131[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
132[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
132[读]MyCache{key='password', value='密码', isEmpty=false}
133[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
133[读]MyCache{key='username', value='用户名', isEmpty=false}
134[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
134[读]MyCache{key='password', value='密码', isEmpty=false}
135[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
135[读]MyCache{key='username', value='用户名', isEmpty=false}
136[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
136[读]MyCache{key='password', value='密码', isEmpty=false}
137[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
137[读]MyCache{key='username', value='用户名', isEmpty=false}
138[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
138[读]MyCache{key='password', value='密码', isEmpty=false}
139[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
139[读]MyCache{key='username', value='用户名', isEmpty=false}
140[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
140[读]MyCache{key='password', value='密码', isEmpty=false}
141[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
141[读]MyCache{key='username', value='用户名', isEmpty=false}
142[读]MyCache{key='password', value='密码', isEmpty=false}
142[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
143[读]MyCache{key='username', value='用户名', isEmpty=false}
143[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
144[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
144[读]MyCache{key='password', value='密码', isEmpty=false}
145[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
145[读]MyCache{key='username', value='用户名', isEmpty=false}
146[读]MyCache{key='password', value='密码', isEmpty=false}
146[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
147[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
147[读]MyCache{key='username', value='用户名', isEmpty=false}
148[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
148[读]MyCache{key='password', value='密码', isEmpty=false}
149[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
149[读]MyCache{key='username', value='用户名', isEmpty=false}
150[读]MyCache{key='password', value='密码', isEmpty=false}
150[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
151[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
151[读]MyCache{key='username', value='用户名', isEmpty=false}
152[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
152[读]MyCache{key='password', value='密码', isEmpty=false}
153[读]MyCache{key='username', value='用户名', isEmpty=false}
153[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
154[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
154[读]MyCache{key='password', value='密码', isEmpty=false}
155[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
155[读]MyCache{key='username', value='用户名', isEmpty=false}
156[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
156[读]MyCache{key='password', value='密码', isEmpty=false}
157[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
157[读]MyCache{key='username', value='用户名', isEmpty=false}
158[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
158[读]MyCache{key='password', value='密码', isEmpty=false}
159[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
159[读]MyCache{key='username', value='用户名', isEmpty=false}
160[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
160[读]MyCache{key='password', value='密码', isEmpty=false}
161[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
161[读]MyCache{key='username', value='用户名', isEmpty=false}
162[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
162[读]MyCache{key='password', value='密码', isEmpty=false}
163[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
163[读]MyCache{key='username', value='用户名', isEmpty=false}
164[读]MyCache{key='password', value='密码', isEmpty=false}
164[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
165[读]MyCache{key='username', value='用户名', isEmpty=false}
165[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
166[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
166[读]MyCache{key='password', value='密码', isEmpty=false}
167[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
167[读]MyCache{key='username', value='用户名', isEmpty=false}
168[读]MyCache{key='password', value='密码', isEmpty=false}
168[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
169[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
169[读]MyCache{key='username', value='用户名', isEmpty=false}
170[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
170[读]MyCache{key='password', value='密码', isEmpty=false}
171[读]MyCache{key='username', value='用户名', isEmpty=false}
171[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
172[读]MyCache{key='password', value='密码', isEmpty=false}
172[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
173[读]MyCache{key='username', value='用户名', isEmpty=false}
173[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
174[读]MyCache{key='password', value='密码', isEmpty=false}
174[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
175[读]MyCache{key='username', value='用户名', isEmpty=false}
175[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
176[读]MyCache{key='password', value='密码', isEmpty=false}
176[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
177[读]MyCache{key='username', value='用户名', isEmpty=false}
177[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
178[读]MyCache{key='password', value='密码', isEmpty=false}
178[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
179[读]MyCache{key='username', value='用户名', isEmpty=false}
179[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
180[读]MyCache{key='password', value='密码', isEmpty=false}
180[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
181[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
181[读]MyCache{key='username', value='用户名', isEmpty=false}
182[读]MyCache{key='password', value='密码', isEmpty=false}
182[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
183[读]MyCache{key='username', value='用户名', isEmpty=false}
183[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
184[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
184[读]MyCache{key='password', value='密码', isEmpty=false}
185[读]MyCache{key='username', value='用户名', isEmpty=false}
185[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
186[读]MyCache{key='password', value='密码', isEmpty=false}
186[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
187[读]MyCache{key='username', value='用户名', isEmpty=false}
187[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
188[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
188[读]MyCache{key='password', value='密码', isEmpty=false}
189[读]MyCache{key='username', value='用户名', isEmpty=false}
189[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
190[读]MyCache{key='password', value='密码', isEmpty=false}
190[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
191[读]MyCache{key='username', value='用户名', isEmpty=false}
191[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
192[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
192[读]MyCache{key='password', value='密码', isEmpty=false}
193[读]MyCache{key='username', value='用户名', isEmpty=false}
193[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
194[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
194[读]MyCache{key='password', value='密码', isEmpty=false}
195[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
195[读]MyCache{key='username', value='用户名', isEmpty=false}
196[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
196[读]MyCache{key='password', value='密码', isEmpty=false}
197[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
197[读]MyCache{key='username', value='用户名', isEmpty=false}
198[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
198[读]MyCache{key='password', value='密码', isEmpty=false}
199[读]MyCache{key='username', value='用户名', isEmpty=false}
199[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
200[读]MyCache{key='password', value='密码', isEmpty=false}
200[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
201[读]MyCache{key='username', value='用户名', isEmpty=false}
201[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
202[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
202[读]MyCache{key='password', value='密码', isEmpty=false}
203[读]MyCache{key='username', value='用户名', isEmpty=false}
203[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
204[读]MyCache{key='password', value='密码', isEmpty=false}
204[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
205[读]MyCache{key='username', value='用户名', isEmpty=false}
205[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
206[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
206[读]MyCache{key='password', value='密码', isEmpty=false}
207[读]MyCache{key='username', value='用户名', isEmpty=false}
207[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
208[读]MyCache{key='password', value='密码', isEmpty=false}
208[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
209[读]MyCache{key='username', value='用户名', isEmpty=false}
209[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
210[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
210[读]MyCache{key='password', value='密码', isEmpty=false}
211[读]MyCache{key='username', value='用户名', isEmpty=false}
211[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
212[读]MyCache{key='password', value='密码', isEmpty=false}
212[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
213[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
213[读]MyCache{key='username', value='用户名', isEmpty=false}
214[读]MyCache{key='password', value='密码', isEmpty=false}
214[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
215[读]MyCache{key='username', value='用户名', isEmpty=false}
215[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
216[读]MyCache{key='password', value='密码', isEmpty=false}
216[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
217[读]MyCache{key='username', value='用户名', isEmpty=false}
217[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
218[读]MyCache{key='password', value='密码', isEmpty=false}
218[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
219[读]MyCache{key='username', value='用户名', isEmpty=false}
219[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
220[读]MyCache{key='password', value='密码', isEmpty=false}
220[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
221[读]MyCache{key='username', value='用户名', isEmpty=false}
221[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
222[读]MyCache{key='password', value='密码', isEmpty=false}
222[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
223[读]MyCache{key='username', value='用户名', isEmpty=false}
223[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
224[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
224[读]MyCache{key='password', value='密码', isEmpty=false}
225[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
225[读]MyCache{key='username', value='用户名', isEmpty=false}
226[读]MyCache{key='password', value='密码', isEmpty=false}
226[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
227[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
227[读]MyCache{key='username', value='用户名', isEmpty=false}
228[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
228[读]MyCache{key='password', value='密码', isEmpty=false}
229[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
229[读]MyCache{key='username', value='用户名', isEmpty=false}
230[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
230[读]MyCache{key='password', value='密码', isEmpty=false}
231[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
231[读]MyCache{key='username', value='用户名', isEmpty=false}
232[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
232[读]MyCache{key='password', value='密码', isEmpty=false}
233[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
233[读]MyCache{key='username', value='用户名', isEmpty=false}
234[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
234[读]MyCache{key='password', value='密码', isEmpty=false}
235[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
235[读]MyCache{key='username', value='用户名', isEmpty=false}
236[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
236[读]MyCache{key='password', value='密码', isEmpty=false}
237[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
237[读]MyCache{key='username', value='用户名', isEmpty=false}
238[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
238[读]MyCache{key='password', value='密码', isEmpty=false}
239[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
239[读]MyCache{key='username', value='用户名', isEmpty=false}
240[读]MyCache{key='password', value='密码', isEmpty=false}
240[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
241[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
241[读]MyCache{key='username', value='用户名', isEmpty=false}
242[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
242[读]MyCache{key='password', value='密码', isEmpty=false}
243[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
243[读]MyCache{key='username', value='用户名', isEmpty=false}
244[读]MyCache{key='password', value='密码', isEmpty=false}
244[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
245[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
245[读]MyCache{key='username', value='用户名', isEmpty=false}
246[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
246[读]MyCache{key='password', value='密码', isEmpty=false}
247[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
247[读]MyCache{key='username', value='用户名', isEmpty=false}
248[读]MyCache{key='password', value='密码', isEmpty=false}
248[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
249[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
Process finished with exit code -1
结果:
可以看到末行249[写]没有对应的249[读]。
分析:
启动基于同一个缓存的两个线程
写->读->写
打印内容:
...
240[读]MyCache{key='password', value='密码', isEmpty=false}
241[读]MyCache{key='username', value='用户名', isEmpty=false}
241[写]-----------------------------MyCache{key='username', value='用户名', isEmpty=false}
242[写]-----------------------------MyCache{key='password', value='密码', isEmpty=false}
思考:执行的时候写线程明明写完了,也把标记值更新了,但是读线程那边出现阻塞了,什么情况?
分析:没有volatile修饰或synchronized加锁,共享变量在多线程(并行程序)中会出现可见性问题。也就是不能实现实时可见,但最终还是可见的。
这就是为什么明明写线程更新了值(还没有刷回内存),但是读线程依然拿了未更新的旧值,按道理不是应该阻塞一会吗,为什么一直阻塞呢?
现在的电脑一般都是多核CPU,有的处理器缓存的层级多,有的少,并且有的处理器可能有时候不会去同步主内存中最新的值,而一直从缓存获取值。
所以这就表现在程序中,刚开始,cpu调度的线程,会去主内存拿最新值,最后却不去拿了。
至此,又有疑问了,为什么最终会有cpu一直从缓存获取值呢?
这个我也不太确定,我觉的,可能是因为随着程序的运行,cpu的缓存越来越大,为了性能,最后处理器会直接从缓存中拿值。
解决多线程可见性问题:
1)使用volatile
2)使用synchronized
常用方法小结:
yield(): 礼让。它能够让当前线程从“运行状态”进入到“就绪状态”,让出cpu执行权,从而让其他等待线程可以执行,但是也有可能重新调度到自己。
waite(): 等待。将当前运行的线程挂起(即让其进入阻塞状态,将执行机会让给其他线程),直到被notify或notifyAll方法唤醒,继续执行。[会释放锁]
notify(): 单一通知。只能随机唤醒一个等待的线程,让其继续执行。
notifyAll(): 全部通知。唤醒所有等待的线程,让他们继续执行。
sleep(): 睡眠。让当前线程睡眠指定的时长,会暂时让出指定时长的CPU执行权,苏醒后,线程就处于就绪状态(可运行状态),然后参与CPU的调度,获取到CPU资源后就可以继续执行了。也就是说,当前线程睡眠完以后,一定会执行,但是不一定会立刻执行。[不会释放锁]
join(): 插队。让一个插队线程强制运行,此时,被插队的线程无法运行,必须等待插队线程执行完之后才可以继续执行。比如在主线程中执行t1.join(),那么子线程t1优先执行,执行完以后,主线程继续执行,同时不影响处在运行状态的其他线程(非主线程)。简单的说,就是插队线程因为插队而优先执行,它只影响被插队线程的执行,不影响其他线程的执行。