如何解决Java volatile变量无法正常运行
谁能解释为什么它在这里不起作用?由于我被声明为volatile,因此应该保护它免受内存不一致的影响。
它受到保护,但不幸的i++
是不是原子操作。它实际上是读取/递增/存储。因此,volatile
这不会使您摆脱线程之间的竞争状况。您可能会从程序中获得以下操作顺序:
- 线程#1读取
i
,得到10 - 之后,线程#2读取
i
,得到10 - #1线程
i
增加到11 - 线程#2递增
i
到11 - 线程#1将11存储到
i
- 线程2将11存储到
i
如您所见,即使发生了2个增量,并且线程之间的值已正确同步,竞争条件也意味着该值仅增加了1。请看此美观的说明。这是另一个很好的答案:Java线程中的volatile int是安全的吗?
您应该使用的是AtomicInteger
允许您从多个线程安全地递增的内容。
static final AtomicInteger i = new AtomicInteger(0);
...
for (int j = 0; j<1000000; j++) {
i.incrementAndGet();
}
解决方法
public class MyThread
{
volatile static int i;
public static class myT extends Thread
{
public void run ()
{
int j = 0;
while(j<1000000){
i++;
j++;
}
}
}
public static void main (String[] argv)
throws InterruptedException{
i = 0;
Thread my1 = new myT();
Thread my2 = new myT();
my1.start();
my2.start();
my1.join();
my2.join();
System.out.println("i = "+i);
}
}
由于易失性构建发生在关系之前,因此i的最终值应严格为2000000。但是,实际结果与变量i不具有易失性没有什么不同。谁能解释为什么它在这里不起作用?由于我被声明为volatile,因此应该保护它免受内存不一致的影响。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。