今日在测试volatile与synchronized特性的时候遇到的一个坑:
先上示例代码:
图1和图2代码本质上的区别是 新线程的i=i+1操作下多了println操作。
本质上的流程来说。讲status设置为false后应该打印i++多次后的结果。但是由于新线程status一开始是保存在工作内存中。
没有同步主内存中的status。因此while循环会一直执行。因此图1是正确的结果。但是图2加了输出操作后。发现while循环
中断了。相当于status加了volatile的效果。
以上只是验证前的猜测,但是如果只是工作内存的问题,那在多次运行的情况下,应该是少次出现上述问题,而不是一直出现(工作内存会自动同步到主内存中,上述问题猜测的话也是在多线程情况下会出现的可见性问题)。
后来验证得知是因为jit(即时编译器对运行的代码做了重排序的问题)
该代码while循环,即时编译器做了优化。运行时变成如下代码:
由此验证上述存在的问题。
因此说明println能达到跟volatile的效果。说明println禁用了重排序。当点击进println源代码后会发现。
println源码进行synchronized操作。这就解开疑惑了。我们都知道synchronized会禁用重排序。因此这个小坑也算告一段落了。