由于Java中的运算并非是原子操作,所以导致volatile声明的变量无法保证线程安全。
对于这句话,我给大家举个例子。代码如下:
最终的打印结果会是1000 * 10 = 10000吗?答案是否定的。
问题就出现在t = t + 1这句代码中。我们来分析一下
例如:
线程1读取了t的值,假如t = 0。之后线程2读取了t的值,此时t = 0。
然后线程1执行了加1的操作,此时t = 1。但是这个时候,处理器还没有把t = 1的值写回主存中。这个时候处理器跑去执行线程2,注意,刚才线程2已经读取了t的值,所以这个时候并不会再去读取t的值了,所以此时t的值还是0,然后线程2执行了对t的加1操作,此时t =1 。
这个时候,就出现了线程安全问题了,两个线程都对t执行了加1操作,但t的值却是1。所以说,volatile关键字并不一定能够保证变量的安全性。
刚才虽然说,volatile关键字不一定能够保证线程安全的问题,其实,在大多数情况下volatile还是可以保证变量的线程安全问题的。所以,在满足以下两个条件的情况下,volatile就能保证变量的线程安全问题:
运算结果并不依赖变量的当前值,或者能够确保只有单一的线程修改变量的值。
变量不需要与其他状态变量共同参与不变约束。
讲到这里,关于volatile关键字的就算讲完了。如果有哪里讲的不对的地方,非常欢迎你的指点。下篇应该会讲synchronize关键字。
完
参考书籍:
深入理解Java虚拟机(JVM高级特性与最佳实践)。
Java并非编程实战
如果你习惯在微信看文章,欢迎关注公众号:苦逼的码农,获取更多原创文章,后台回复”礼包”送你一份资源大礼包。