以下代码存在于“Under theTallnding the JVM Advanced Features and Best Practices,second Edition”的第13章中。 但是当线程执行“while(Thread.activeCount()> 1)”时,它将被阻止,并且不会打印任何内容。
public class Code_12_1 {
public static AtomicInteger race = new AtomicInteger(0);
public static void increment(){
race.incrementAndGet();
}
private static final int THREADS_COUNT = 20;
public static void main(String[] args) throws Exception{
Thread[] threads = new Thread[THREADS_COUNT];
for (int i = 0; i < THREADS_COUNT; i++) {
threads[i] = new Thread(new Runnable() {
@Override
public void run() {
for (int j = 0; j < 10000; j++) {
increment();
}
}
});
threads[i].start();
}
while (Thread.activeCount() > 1)
Thread.yield();
System.out.println(race);
}
}
但是当我将“while(Thread.activeCount()&gt; 1)”更改为“while(Thread.activeCount()&gt; 2)”时,线程可以正确执行并输出答案200000.
那么,为什么线程在执行时会被阻塞“while(Thread.activeCount()&gt; 1)”?
答案 0 :(得分:0)
我已经弄清楚了。我运行你的代码,事实证明,除了主线程之外,最初(在当前的ThreadGroup中)还有另一个Thread运行,甚至在你所有其他线程之前。所以,下面的print语句给了我一个2的计数(参见initialCount):
public static void main(String[] args) throws Exception{
Thread[] threads = new Thread[THREADS_COUNT];
int initialCount = Thread.activeCount();
System.out.println("Initial count: " + initialCount);
for (int i = 0; i < THREADS_COUNT; i++) {
threads[i] = new Thread(new Runnable() {
@Override
public void run() {
for (int j = 0; j < 10000; j++) {
increment();
}
}
});
threads[i].start();
}
while (Thread.activeCount() > 1){
System.out.println(race);
System.out.println(Thread.activeCount());
Thread.yield();
}
}
所以,你要做的是:
while (Thread.activeCount() > initialCount){
Thread.yield();
}
而且,它会按预期工作。
推理:它被阻止,因为你的所有线程在你启动它们之后就完成了执行,然后你剩下这个额外的线程永远不会让你退出while循环。
如果在Thread.yield()
之前插入打印语句,则会得到类似
200000
200000
200000
200000
200000
200000
...
...
这支持了所有线程都已完成并且只留下2个保持循环运行的原因。