在JAVA中,每个线程都有一块属于自己的工作内存区,该内存区会保存一份从主内存拷贝过来的公共变量值。不加volatile修身的变量在每个线程中的值修改一般都是独立的。及如下图所示。
1.开始执行时A、B线程从主内存区load变量i=0.此时值是一样的。
2.当B线程将变量i=1时,此时并不会立刻写入i=1到主内区,所以A线程工作区i还是等于0.
3.如果i变量用Volatile修饰后,B线程改变变量i的值,会立刻返回写回主内存区中。如下图所示。
package list; public class Test { volatile int i = 0; public void tryExit() { if (i != i) {//当左边i读取内存值后,swapValue立刻改变了 i的值,当右i读取内存值,就会发现值变化了, //所以程序就会出现i的值可以两边不一样的结果出现。如果不加volatile立刻更新值,应该会一直执行下去 System.out.println(i + " " + i); System.exit(0); } } public void swapValue() { i = i + 1; } public static void main(String[] args) { final Test volObj = new Test(); Thread mainThread = new Thread() { public void run() { System.out.println("mainThread start"); while (true) { volObj.tryExit(); } } }; mainThread.start(); Thread swapThread = new Thread() { public void run() { System.out.println("swapThread start"); while (true) { volObj.swapValue(); } } }; swapThread.start(); try { Thread.sleep(10000); } catch (InterruptedException e) { e.printStackTrace(); } } }
当使用volatile修饰变量i时,某个线程改变i的值时,会写回到主内存区,从而每个线程在使用时会是最新的值。 但不能代替synchronized,因为当A线程中,B线程中 i变量都为1时,某个时间AB线程同时执行i++. 最终i的值会为2.因为没有锁。这点需要注意下。
时间: 2024-11-09 10:45:07