Java 易失性原子整数不工作
嗨,我在试。我从主线程创建10个线程,并打印每个线程的静态计数器值 产量不确定。有人能告诉我为什么它不工作吗Java 易失性原子整数不工作,java,multithreading,Java,Multithreading,嗨,我在试。我从主线程创建10个线程,并打印每个线程的静态计数器值 产量不确定。有人能告诉我为什么它不工作吗 public class Main { static AtomicInteger counter = new AtomicInteger(0); public static void main(String[] args) { while(counter.getAndIncrement() < 10){ new Threa
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();
}
}
}
我最讨厌的是
3 3 6 7 7 10 11 11
每次输出都不同。
我不希望它们按正确的顺序排列,但我希望它们的值在0到10之间是唯一的。您有一个线程递增该值,多个线程获取并显示该值。显然,在递增线程执行它的任务时,存在很多潜在的问题,然后其余线程打印相同的值。调用start并不意味着线程将在值增加之前运行 相反,如果您将just get放入while循环,并在其他线程中使用incrementAndGet,那么您将获得唯一的值,尽管您可能会获得10个以上的值 如果您想要精确打印10个不同的值,那么代码将无法工作 使用原始代码,您可以创建10个线程,但当它们运行时,它们将打印计数器的当前值。如果启动的线程中有3个运行,它们将始终打印相同的值 当您将get移动到while循环中时,它可以并且将创建10个以上的线程,因为增量计数器的其他线程还没有机会运行,这导致在10个增量线程运行之前创建线程。在此之后,仍然有创建的线程,但尚未运行->您将获得10多个额外线程
如果要使用线程,则无法使用单个计数器变量获得所需的输出。您有一个递增值的线程和多个获取并显示值的线程。显然,在递增线程执行它的任务时,存在很多潜在的问题,然后其余线程打印相同的值。调用start并不意味着线程将在值增加之前运行 相反,如果您将just get放入while循环,并在其他线程中使用incrementAndGet,那么您将获得唯一的值,尽管您可能会获得10个以上的值 如果您想要精确打印10个不同的值,那么代码将无法工作 使用原始代码,您可以创建10个线程,但当它们运行时,它们将打印计数器的当前值。如果启动的线程中有3个运行,它们将始终打印相同的值 当您将get移动到while循环中时,它可以并且将创建10个以上的线程,因为增量计数器的其他线程还没有机会运行,这导致在10个增量线程运行之前创建线程。在此之后,仍然有创建的线程,但尚未运行->您将获得10多个额外线程 如果要使用线程,则无法使用单个计数器变量获得所需的输出。调用
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();
}
当你打电话的时候
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();
}
在一个线程中增加值,然后在另一个线程中获得值。你为什么期望它们是独一无二的?将getAndIncrement调用移到创建的线程中。谢谢keppil。好啊我还尝试了在run和get中使用getAndIncrement方法来检入while循环。在这种情况下,输出是按顺序进行的,但我的条件失败,它将打印10多个值。1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16. 因此我把它改为上面的。你在一个线程中增加值,然后在另一个线程中得到值。你为什么期望它们是独一无二的?将getAndIncrement调用移到创建的线程中。谢谢keppil。好啊我还尝试了在run和get中使用getAndIncrement方法来检入while循环。在这种情况下,输出是按顺序进行的,但我的条件失败,它将打印10多个值。1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16. 所以我把它改成上面的。我还尝试了在run和get中使用getAndIncrement方法来检入while循环。在这种情况下,输出是按顺序进行的,但我的条件失败,它将打印10多个值。1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16. 我在下面的评论中使用了Peter Lawrey的建议,并使用了一个局部变量。效果很好。谢谢。我还尝试了在run和get中使用getAndIncrement方法来检入while循环。在这种情况下,输出是按顺序进行的,但是
我的条件失败,它将打印超过10个值。1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16. 我在下面的评论中使用了Peter Lawrey的建议,并使用了一个局部变量。效果很好。谢谢,谢谢。使用局部变量有帮助。谢谢。使用局部变量有帮助。