当我在线程 T1
中更新 i
的值时,该值对线程 T2
不可见 - 为什么?理论上, 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++;
}
}
}
最佳答案
我不知道您希望代码输出什么,但是:
请注意,即使变量是 volatile 的,x++
是 x = x + 1
的快捷方式。它不是原子的,并且执行单独的读取和写入操作,该值可能会被两个操作之间的另一个线程更改。
在你的情况下,对于变量 i
,只有一个线程正在写入变量,因此这应该不是问题。
但是对于 j
,两个线程正在执行 j++
在同一个变量上。对于某些迭代,一个线程有可能写入 j
另一个线程的读写之间。导致之前的写入被忽略。
为了避免这种情况,您可以:
- 执行
j++
在synchronized
block - 使用
AtomicInteger
而不是volatile int
还有一点就是j <= 10
上的测试在增量之前完成。所以两个线程可能会进入while
对于 j==10
时的迭代,结果是 j==12
(或者当还涉及上述效果时甚至会有所不同)。
要解决这个问题,您可以直接在 while
中递增条件,使用 AtomicInteger
例如:
while(j.getAndIncrement() <= 10)
关于java - java中的 volatile 关键字对其他线程不可见,下面是我的代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25626111/