标签:string start print int 操作符 拷贝 throws 内存 停止线程
一 , 概述
在JVM的内存模型之中,多个线程会拷贝一份主内存的内容到自己的栈之中,因此在线程运行的时候会首先从自己的栈中寻找这个副本,而不是
首先到主内存之中查询.因此,一个线程修改了这个变量,其它的线程是看不见的.
解决线程的安全性问题一种方式就是解决这种可见性的问题.
传统的,我们可以使用轻量级的volatile关键词来解决.
二 .测试例子:
public class VolatileTest extends Thread { private boolean isRunning = true; public boolean isRunning() { return isRunning; } public void setRunning(boolean isRunning) { this.isRunning = isRunning; } public void run() { System.out.println("进入了run..............."); while (isRunning) { } System.out.println("isUpdated的值被修改为为false,线程将被停止了"); } public static void main(String[] args) throws InterruptedException { VolatileTest volatileThread = new VolatileTest(); volatileThread.start(); Thread.sleep(1000); volatileThread.setRunning(false); // 停止线程 } }
我们运行上面的程序,发现我们就是修改了标记位,线程依然无法终结.
三 . 原因的分析
当我们创建了一个线程,该线程在运行的时候会将标记位拷贝到自己线程栈之中,此后自己就去使用这个副本了,即使我们修改的主体,线程依然不知道这个标记被修改了.
四 . 解决
我们只需要在这个变量上面加上加上volatile关键词就可以完成.
private volatile boolean isRunning = true;
总结 : 该关键词的作用就是实现可见性.
当线程对副本的修改会被反映到主存之中,就实现了可见性.
这个关键词只能实现一个弱化的同步功能,我们不能依赖这种操作.
原理: 强制JVM刷新副本的内容到贮存之中.
同时该操作符还能对指令重排序做出影响,这个在后面会说到.
标签:string start print int 操作符 拷贝 throws 内存 停止线程
原文地址:https://www.cnblogs.com/trekxu/p/8976906.html