/**
* 线程的开销 : 线程的创建和销毁
* 线程的上下文切换和调度
* 线程的同步
*
*
* 多线程的内存模型: 线程独有的工作内存(线程缓存用于提高效率)---------所有线程共享的主内存
*
* 线程读取在主内存的成员变量(即共享变量)的过程:
* 1. 线程的工作内存会去读取主内存的成员变量并保存副本
* 2. 线程在工作内存中修改副本
* 3. 将修改后的副本的值推送给主空间并改写主空间该成员变量的值
* 4. 主空间成员变量修改后的值将不会主动推送给其他线程, 这就造成了线程的工作内存的共享变量的不同步
*
* 问题: 各个线程的工作内存不可见
* 即 A线程先读取共享变量a, B线程修改了共享变量a后为a`,推送给主内存并改写, 主内存不会推送给A线程,A和B的变量会不同步
*
* 解决办法
* synchroized可以同步值
* volatile关键字 会使得主内存的共享变量每经过一次改变都会推送给其他的线程, 其他线程会修改其副本
*
* 同步值之synchronized和volatile的区别
* synchronized块只能使用对象作为它的参数(锁是基于对象的),简单类型的变量(如int、char、boolean等),不能使用synchronized来同步
* volatile用来同步简单类型的变量,简单类型的变量(如int、char、boolean等)
*
* 总结: 主内存 工作内存
* 共享变量 副本
* 工作内存中会主动去拉去主内存的共享变量
* 工作内存中的副本修改后会推送给主内存改写共享变量
* volatile 会使得主内存修改后的共享变量推送其他线程
*
* 内存不可见的本质 : 线程之间有互相独立的缓存即, 当多个线程对共享数据进行操作时, 其操作彼此不可见
* 使用场景: 一个线程在读共享变量 另一个线程在改写共享变量
*
*/
public class VolatileTest {
public static void main(String[] args) throws InterruptedException {
MyTask task = new MyTask();
new Thread(task).start();
while (true){
//读取值
//直接用线程缓存的值 不会去主内存去拉取变量
if (task.isFlag()){
System.out.println("=============");
break;
}
/*
synchronized (task){
if (task.isFlag()){
System.out.println("=============");
break;
}
}*/
}
}
}
class MyTask implements Runnable{
private volatile boolean flag = false;
// 修改值
@Override
public void run() {
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
flag = true;
System.out.println("flag=" + flag);
}
public boolean isFlag() {
return flag;
}
}