Java多线程中读写不一致问题
问题:
假设有个全局变量var初始化为0
MyThread线程循环+1
MyThread2线程检测到var大于10时退出循环
问题来了,我们发现MyThread一直没有退出循环
也就是说线程没有及时刷新内存
解决方法:给全局变量添加 volatile关键字
Java提供了volatile来保证可见性。当一个变量被volatile修饰后,表示着线程本地内存无效,当一个线程修改共享变量后他会立即被更新到主内存中,当其他线程读取共享变量时,它会直接从主内存中读取。
点击查看代码
abstract class ThreadMemo implements Runnable {
private Thread t;
protected String threadName;
// public static int var = 0;
volatile public static int var = 0; // 只需要添加volatile关键字就可以了
public ThreadMemo(String name) {
threadName = name;
System.out.println("Creating " + threadName);
}
abstract public void run();
public void start() {
System.out.println("Starting " + threadName);
if (t == null) {
t = new Thread(this, threadName);
t.start();
}
}
}
class MyThread extends ThreadMemo {
MyThread(String name) {
super(name);
}
public void run() {
var = super.var;
while(true) {
var = var + 1;
// sleep(50);
// time.sleep(50);
try {
Thread.sleep(50);
} catch (InterruptedException e) {
System.out.println("Thread " + threadName + " interrupted.");
}
// System.out.println("mythread 1 var: " + var);
}
}
}
class MyThread2 extends ThreadMemo {
MyThread2(String name) {
super(name);
}
public void run() {
var = super.var;
while(true) {
if(var < 10) {
// try {
// Thread.sleep(1);
// } catch (InterruptedException e) {
// System.out.println("Thread " + threadName + " interrupted.");
// }
// Object o = new Object();
continue;
}
System.out.println("mythread2 var = " + var);
break;
}
}
}
public class Test2 {
// public static int var = 0;
public static void main(String[] args) {
ThreadMemo t1 = new MyThread("Thread-1");
ThreadMemo t2 = new MyThread2("Thread-2");
Thread a = new Thread(t1);
Thread b = new Thread(t2);
a.start();
b.start();
}
}
然后我们发现,给读线程的循环中添加一些语句,循环就能退出了
V2EX上发现相同的问题 Java 多线程并发,线程什么时候会刷新 "工作内存"
据说是遇到IO阻塞才会刷新内存
个性签名:时间会解决一切