并发中的i++安全问题浅述

来源:互联网 发布:算法公平和效率 知乎 编辑:程序博客网 时间:2024/06/08 03:49

*多线程操作同一变量*

此处不可能是局部变量,肯定是成员变量或静态变量
PS:为什么不可能是局部变量?

需要多线程访问局部变量,那么多个线程就必须在方法中进行定义,如使用匿名内部类方式定义多个线程。
在使用匿名内部类引用局部变量时,局部变量必须通过final来修饰。这样做的原因是变量的生命周期问题。
final修饰的变量,不管是int还是Integer,都不能进行自加操作。

在A线程执行i++结束后,如果没有及时把缓存中的结果刷新到主内存,B线程就开始执行i++操作,那么结果就会出错。
解决方案:使用volatile关键字修饰。

i++的总体过程可以分为

tp = i //1
tp2 = tp+1 //2
i = tp2 //3

volatile关键字

在 java 垃圾回收整理一文中,描述了jvm运行时刻内存的分配。其中有一个内存区域是jvm虚拟机栈,每一个线程运行时都有一个线程栈,

线程栈保存了线程运行时候变量值信息。当线程访问某一个对象时候值的时候,首先通过对象的引用找到对应在堆内存的变量的值,然后把堆内存

变量的具体值load到线程本地内存中,建立一个变量副本,之后线程就不再和对象在堆内存变量值有任何关系,而是直接修改副本变量的值,

在修改完之后的某一个时刻(线程退出之前),自动把线程变量副本的值回写到对象在堆中变量。这样在堆中的对象的值就产生变化了。

借鉴总结:http://blog.csdn.net/irving512/article/details/52704031;
http://www.cnblogs.com/aigongsi/archive/2012/04/01/2429166.html

原创粉丝点击