Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
925 views
in Technique[技术] by (71.8m points)

multithreading - JUnit test not executing all threads created within the test

I wrote a simple example for threading which generates tables for numbers starting from 1 to 20. when I tested it with main method it executes all the threads (prints all the messages), while all threads are not being run (all messages are not being printed) most of the times (sometimes it runs all the threads) when doing the same with JUnit test. I think there should not be any difference in terms of output.

Here is the class with main method:

public class Calculator implements Runnable {

    private int number;

    Calculator(final int number){
        this.number = number;
    }

   @Override
   public void run() {
        for(int i = 1; i <= 10; i++){
            System.out.printf("%s : %d * %d =  %d 
", Thread.currentThread().getName(), number, i, number * i);
        }

   }

    public static void main(String[] args){
        Calculator calculator = null;
        Thread thread = null;
        for(int i = 1; i < 21; i ++){
            calculator = new Calculator(i);
            thread = new Thread(calculator);
            System.out.println(thread.getName() + " Created");
            thread.start();
            System.out.println(thread.getName() + " Started");
        }

     }

}

When I invoke the main method it prints all the results.

Bellow is the code for JUnit test equivalent to the main method:

public class CalculatorTest {

private Calculator calculator;
private Thread thread;

@Test
public void testCalculator() {
    for(int i = 1; i < 21; i ++){
        calculator = new Calculator(i);
        thread = new Thread(calculator);
        System.out.println(thread.getName() + " Created");
        thread.start();
        System.out.println(thread.getName() + " Started");
     }
 }

}

When I run the above test case, the behavior of the output is not consistant in the scene that sometimes it prints all the messages and most of the times prints only a few and exits. Here is the output captured in case of the above JUnit test case:

Thread-0 Created
Thread-0 Started
Thread-1 Created
Thread-1 Started
Thread-2 Created
Thread-2 Started
Thread-3 Created
Thread-3 Started
Thread-4 Created
Thread-4 Started
Thread-5 Created
Thread-5 Started 
Thread-6 Created
Thread-6 Started
Thread-7 Created
Thread-7 Started
Thread-8 Created
Thread-8 Started
Thread-9 Created
Thread-9 Started
Thread-10 Created
Thread-10 Started
Thread-11 Created
Thread-11 Started
Thread-12 Created
Thread-12 Started
Thread-13 Created
Thread-13 Started
Thread-14 Created
Thread-14 Started
Thread-15 Created
Thread-15 Started
Thread-16 Created
Thread-16 Started
Thread-17 Created
Thread-17 Started
Thread-18 Created  
Thread-18 Started
Thread-19 Created 
Thread-19 Started
Thread-0 : 1 * 1 =  1 
Thread-0 : 1 * 2 =  2 
Thread-0 : 1 * 3 =  3 
Thread-0 : 1 * 4 =  4 
Thread-0 : 1 * 5 =  5 
Thread-0 : 1 * 6 =  6 
Thread-0 : 1 * 7 =  7 
Thread-0 : 1 * 8 =  8 
Thread-0 : 1 * 9 =  9 
Thread-0 : 1 * 10 =  10 
Thread-2 : 3 * 1 =  3 
Thread-2 : 3 * 2 =  6 
Thread-2 : 3 * 3 =  9 
Thread-2 : 3 * 4 =  12 
Thread-2 : 3 * 5 =  15 
Thread-2 : 3 * 6 =  18 
Thread-2 : 3 * 7 =  21 

Output ends here without printing the remaining messages in other threads/ executing other threads.

Can somebody help me to understand the reason behind this. Thanks in advance.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

JUnit is exiting the test method early. You need to wait for all of the threads to complete before you exit the testCalculator() method.

An easy way to do that is by using a CountDownLatch.

  1. Initialize a CountDownLatch with CountDownLatch latch = new CountDownLatch(20).

  2. Pass each Calculator runnable a reference to the latch. At the end of the run() method, call latch.countDown().

  3. At the end of the testCalculator() method call latch.await(). This will block until latch.countDown() has been called 20 times (i.e. when all threads have completed).


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...