为什么线程在执行代码“while(Thread.activeCount()> 1)”时会被阻塞?

时间:2017-05-10 08:35:14

标签: java multithreading

以下代码存在于“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)”?

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个保持循环运行的原因。