Thread.sleep在ExecutorService循环中导致意外行为

时间:2013-09-18 19:08:27

标签: java multithreading junit executorservice

在下面的测试类中输出“before”。

但是如果我删除了Thread.sleep,则输出以下内容:

before
after
before
after
before
after
before
after
before
after
before
after
before
after
before
after
before
after
before
after

这是我的期望。

当我使用Thread.sleep时,我认为

的每个输出之间应该有1000ms的延迟
before
after

为什么这不会发生?如何修改代码,以便无论调用睡眠与否,生成的输出都是相同的?

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import org.junit.Test;

public class RunExecutorTest {

    private ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);

    private class RunTest implements Runnable {
        public void run() {

            System.out.println("before");

            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

            System.out.println("after");
        }
    }

    @Test
    public void testRun() {

        Runnable r = new RunTest();

        for(int counter = 0; counter < 10; ++counter) {  
            executor.execute(r);
        }
    }

}

从下面的阅读评论更新“@ user470184它在junit测试用例中不起作用,因为当主线程完成时Junit会杀死所有线程。 - Sotirios Delimanolis”如果我添加

try {
    Thread.sleep(10000);
} catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}

在测试方法结束时,它按预期工作。

1 个答案:

答案 0 :(得分:4)

  

当我使用Thread.sleep时,我认为应该有1000毫秒的延迟   

的每个输出之间      

前   之后

     

为什么这不会发生?如何修改代码呢?   无论是否呼叫睡眠,生成的输出都相同?

延迟显然在beforeafter之间,而不是在每次迭代之间

System.out.println("before");

try {
    Thread.sleep(1000);
} catch (InterruptedException e) {
    e.printStackTrace();
}

System.out.println("after");

屈服

before
...1000 millis
after
before
...1000 millis
after

也许我误解了你的问题。

执行的线程池为1个线程。

private ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);

所有这些都将按顺序输出。


至于为什么它失败了JUnit,JUnit在其主线程完成执行时杀死所有线程。你无法真正控制它(没有实现你自己的等待机制)。