嗨,我正在尝试挥发性。我从我的主线程创建10个线程,并从每个线程打印静态计数器的值。
输出不确定。任何人都可以让我知道为什么它不起作用。
public class Main {
static AtomicInteger counter = new AtomicInteger(0);
public static void main(String[] args) {
while(counter.getAndIncrement() < 10){
new Thread(new Runnable() {
@Override
public void run() {
try {
System.out.println(counter.get());
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
}
}
在此我还尝试将计数器更改为
static volatile int counter = 0;
我得到的输出是
3 3 6 6 7 7 10 10 11 11
输出每次都不同。 我不希望它们按正确顺序排列,但我希望0到10之间的唯一值。
答案 0 :(得分:6)
您有一个增加值的线程,以及获取并显示该值的多个线程。显然,增量线程有很多潜力可以做到这一点,然后其余线程打印相同的值。仅仅因为你调用start()
并不意味着线程会在值增加之前运行。
如果您只是在{while循环中放置get()
,并在其他主题中使用incrementAndGet()
,那么您将获得唯一值(尽管您可能会获得超过10个)。
如果您想打印10个不同的值,则代码无效。
使用原始代码,您可以创建10个线程,但是当它们运行时,它们将打印计数器的当前值。如果3个已启动的线程运行,它们将始终打印相同的值。
当你将get()
移动到while循环中时,它可以并且将创建超过10个线程,因为增加计数器的其他线程还没有机会运行,导致线程被创建,直到10个递增线程运行。之后仍有剩余的线程被创建,但还没有运行 - &gt;你得到10 +额外的线程。
如果要使用线程,则无法使用单个计数器变量获得所需的输出。
答案 1 :(得分:4)
致电时
counter.getAndIncrement();
以及后来的另一个线程调用
System.out.println(counter.get());
然后这些价值观彼此无关。
如果要保留值,则需要在不变的变量中执行此操作。
for (int i = 0; i < 10; i++) {
final threadId = i;
new Thread(new Runnable() {
@Override
public void run() {
System.out.println(threadId);
}
}).start();
}
不需要使用volatile变量,但如果你真的需要它,你可以做
for (int i = 0; i < 10; i++) {
new Thread(new Runnable() {
@Override
public void run() {
System.out.println(counter.getAndIncrement());
}
}).start();
}