Java volatile变量不';我的行为不正确。 公共类读取 { 挥发性静态inti; 公共静态类myT扩展线程 { 公开作废运行() { int j=0; while(j
有人能解释为什么它在这里不工作吗?因为我被声明为volatile,所以应该保护它不受内存不一致的影响 它是受保护的,但不幸的是,Java volatile变量不';我的行为不正确。 公共类读取 { 挥发性静态inti; 公共静态类myT扩展线程 { 公开作废运行() { int j=0; while(j,java,concurrency,volatile,Java,Concurrency,Volatile,有人能解释为什么它在这里不工作吗?因为我被声明为volatile,所以应该保护它不受内存不一致的影响 它是受保护的,但不幸的是,i++不是一个原子操作。它实际上是读取/增量/存储。因此,volatile不会将您从线程之间的争用条件中拯救出来。您可能会从程序中获得以下操作顺序: 线程#1读取i,得到10 紧接着,线程2读取i,得到10 线程#1将i增加到11 螺纹#2增量i至11 线程#1将11存储到i 线程2将11存储到i 如您所见,即使发生了2次增量,并且线程之间的值已正确同步,争用条件意味着
i++
不是一个原子操作。它实际上是读取/增量/存储。因此,volatile
不会将您从线程之间的争用条件中拯救出来。您可能会从程序中获得以下操作顺序:
i
,得到10i
,得到10i
增加到11i
至11i
i
AtomicInteger
,它允许您从多个线程安全地递增
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);
}
}
静态最终AtomicInteger i=新的AtomicInteger(0);
...
对于(int j=0;jOnlyi
需要是一个AtomicInteger
;j
是线程的纯本地线程。我不确定如何回答@OneZero。将其声明为volatile
将不起作用,因为++不是原子的。您可以在每次更新它或使用AtomicInteger
时对其进行同步。使其volatile
还不够。@OneZero应该解释一下volitile
的用途。不是这个。@OneZero非volitile读取可以从预写值中获取一些位,从后写值中获取一些位,但仅限于基础内存中大于字的类型。double
是最常见的违例者。通常峰值时,大多数并发问题对于volatile
来说太多了,所以请看synchronize
和wait
。@Gray在这个千年期构建的任何东西上的实践中,可能是真的。不过,我不认为这是语言规范中的保证。也许更实际的保证是保留了写入顺序,因此如果您如果是double data
和volitile boolean ready
以及先设置data
再设置ready=true
的代码,那么可以肯定的是,在看到ready
变为true后,数据也会被设置,即使在不同的线程中也是如此。如果没有volatile
k,这是不保证的eyword,您可以看到ready
true,然后data
的值可能没有从写入线程传播。
static final AtomicInteger i = new AtomicInteger(0);
...
for (int j = 0; j<1000000; j++) {
i.incrementAndGet();
}