当我在线程i
中更新T1
的值时,线程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++;
}
}
}
答案 0 :(得分:1)
我不知道您希望代码输出的内容,但是:
请注意,即使变量是易变的,x++
也是x = x + 1
的快捷方式。它不是原子的,并且执行单独的读写操作,这两个操作之间的另一个线程可能会改变该值。
在您的情况下,对于变量i
,只有一个线程正在编写变量,所以它不应该是一个问题。
但对于j
,两个线程在同一个变量上执行j++
。对于某些迭代,有可能一个线程在另一个线程的读写之间写入j
。导致先前的写入被忽略。
要避免这种情况,您可以:
j++
区块中的synchronized
AtomicInteger
代替volatile int
另一点是j <= 10
上的测试是在增量之前完成的。因此,当while
时,两个线程可以输入j==10
进行迭代,从而导致j==12
结束(或者当涉及上述效果时也会有不同的东西)。
要解决此问题,您可以使用while
直接在AtomicInteger
条件中增加:
while(j.getAndIncrement() <= 10)
答案 1 :(得分:0)
您正在从每个线程实例访问本地i - 您的每个线程对象都有自己的i,j,x实例,并且您没有交叉引用它们。
实际上你的线程甚至都不知道那里还有其他线程。