[英]volatile keyword in java is not visible to other threads below is my code
When I update the value of i
in thread T1
, the value is not visible to thread T2
- why? 当我在线程
T1
更新i
的值时,该值对于线程T2
不可见-为什么? Theoretically volatile
variables must retrieve fresh values, but it is not working. 从理论上讲,
volatile
变量必须检索新值,但它不起作用。
class Threads implements Runnable
{
public volatile int i=4;
volatile int j=0;
int x=0;
public static void main(String[] args) {
Threads th=new Threads();
Thread a = new Thread(th);
Thread b=new Thread(th);
a.setName("T1");
a.setPriority(Thread.MAX_PRIORITY);
b.setName("T2");
a.start();
b.start();
}
public int count() {
return ++i;
}
public void run() {
while(j<=10)
{
if(Thread.currentThread().getName().equals("T1"))
{
i++;
System.out.println(Thread.currentThread().getName()+" : "+i);
try
{
Thread.sleep(2);
}catch(Exception ex){}
}
else if(Thread.currentThread().getName().equals("T2"))
{
System.out.println(Thread.currentThread().getName()+" : "+i);
try
{
Thread.sleep(1);
}catch(Exception ex){}
}
j++;
}
}
}
I don't know what you expect your code to output, but: 我不知道您期望代码输出什么,但是:
Note that even if a variable is volatile, x++
is a shortcut for x = x + 1
. 请注意,即使变量是volatile,
x++
也是x = x + 1
的快捷方式。 It is not atomic, and performs separate read and write operations, the value may be changed by another thread between the two operations. 它不是原子的,并且执行单独的读取和写入操作,该值可以由两个操作之间的另一个线程更改。
In your case, for variable i
, only one thread is writing the variable, so it should not be an issue. 在您的情况下,对于变量
i
,只有一个线程正在写入该变量,因此这不是问题。
But for j
, two threads are doing j++
on the same variable. 但是对于
j
,两个线程在同一个变量上执行j++
。 There is probability that, for some iterations, one thread writes j
between the read and write of the other thread. 对于某些迭代,一个线程有可能在另一线程的读写之间写入
j
。 Resulting in the earlier write to be ignored. 导致较早的写入被忽略。
to avoid this, you can either: 为避免这种情况,您可以:
j++
in a synchronized
block synchronized
块中执行j++
AtomicInteger
instead of volatile int
AtomicInteger
而不是volatile int
Another point is that the test on j <= 10
is done before the increment. 另一点是,对
j <= 10
的测试是在递增之前完成的。 So the two threads may enter the while
for an iteration when j==10
, resulting in the end by having j==12
(or even something different when the effect described above is also involved). 因此,当
j==10
,两个线程可能会进入while
进行迭代,结果是j==12
(或者在涉及上述效果时甚至有所不同)。
To solve that, you may increment directly in the while
condition, using an AtomicInteger
for instance: 为了解决这个问题,您可以在
while
条件下直接增加,例如使用AtomicInteger
:
while(j.getAndIncrement() <= 10)
You are accessing the local i from each thread instance - each of your thread objects has their own i, j , x instances and you are not cross referencing them. 您正在从每个线程实例访问本地i-每个线程对象都有自己的i,j和x实例,并且您没有交叉引用它们。
Actually your threads do not even know that there are any other threads out there. 实际上,您的线程甚至都不知道那里还有其他线程。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.