这可能是一个愚蠢的问题但是,这个程序的输出(它的方式)可以为零吗?
public class Test2{
int a = 0;
AtomicInteger b = new AtomicInteger();
public static Test2 c = new Test2();
public static void main(String[] args){
Thread t1 = new Thread(new MyTest1());
Thread t2 = new Thread (new Mytest2());
t1.start();
t2.start();
}
}
class MyTest1 implements Runnable{
public void run(){
Test2.c.a = 1;
Test2.c.b.compareAndSet(0,1);
}
}
class Mytest2 implements Runnable{
public void run(){
int x = 0;
if(Test2.c.b.get() == 1)
x = Test2.c.a;
System.out.println("Value of x = "+x);
}
}
我问这个的原因是,虽然我正在使用AtomicInteger,但MyTest2中的if()语句可能先执行,然后x的值为zero..right?
或者我没有直接思考。
任何帮助都将受到高度赞赏。
答案 0 :(得分:5)
这个程序的输出(它的方式)是零吗?
是的,这是可能的。代码不保证t1
在t2
完成之前完成任何方式。如果这是您的意图,您可能会发现CountdownLatch
或CyclicBarrier
有用。单击链接,它们的javadocs包含代码示例。
那就是说,我宁愿传递AtomicInteger
的引用作为两个runnables的构造函数参数,而不是以静态方式访问它。
答案 1 :(得分:1)
通过一个小的更改,可以保证输出为1
:
public void run(){
int x = 1;
if(Test2.c.b.get() == 1)
x = Test2.c.a;
System.out.println("Value of x = "+x);
}
由于易失性读/写的排序保证:
x
最初是1
x
的唯一其他值是Test2.c.a
Test2.c.a
读取了x
,才能将1
复制到Test2.c.b
仅在将1
写入Test2.c.b
后1
写入Test2.c.a
Test2.c.b
是易失性的,所以读取它的任何线程也会通过写入Test2.c.b
的同一线程观察所有先前对所有变量(易失性或非易失性)的写入。这意味着t2
也会看到1
写入Test2.c.a
Test2.c.b
返回1
以外的内容),则x保留其初始值1
,因此输出仍为1
我怀疑这是该计划的作者试图说明的内容,0
的默认值x
是一个错字。