/**
* Created by Dev_yang on 2016/4/23.
*/
public class ThreadLock2 {
public static void main(String[] args) {
Service service = new Service();
ThreadA threadA = new ThreadA(service);
threadA.start();
ThreadB threadB = new ThreadB(service);
threadB.start();
System.out.println("已经发起停止命令!");
}
}
class Service {
private boolean flag = true;
void run() {
while (flag) {
/* 取消这里的注释即可解决线程间数据不可见问题
synchronized (Service.class){
}*/
}
System.out.println("service stop run!");
}
void changeFlag() {
flag = false;
}
}
class ThreadA extends Thread {
private Service service;
public ThreadA(Service service) {
this.service = service;
}
@Override
public void run() {
service.run();
}
}
class ThreadB extends Thread {
private Service service;
public ThreadB(Service service) {
this.service = service;
}
@Override
public void run() {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
service.changeFlag();
}
}
“`
出现上面现象的原因是因为threadB 线程对于 flag = false;的执行结果对于 线程threadA而言是看不见的,因为每个线程对于变量的读取(第一次读取变量会从主内存读取,第二次就会直接从私有内存读取)或者更改都只会在自己的私有内存当中生效,当该线程执行完自己的代码逻辑时才会将结果刷新到主内存中(为了提高线程执行效率),所以threadA读取的一直就是自己的缓存flag=true的值,因此System.out.println(“service stop run!”);这段代码一直无法被执行,程序陷入死循环。
解决办法:将程序代码中while循环的注释取消,即可让System.out.println(“service stop run!”);得到执行。
解释:synchronized 具有和vilatile相似的功能,当变量的值被修改后,线程私有内存缓存的值会失效,强制其前往主内存中再次读取,当然其对变量值得修改也是立马被刷新到主内存当中