1

I'm new to concurrency in Java. I've used Junit to test some of my code but the result is strange. The code snippet below writes nothing to console when I run it with JUnit (Eclipse) though it successfully executes.

@Test
public void testGetNameWithMultithreading() { 

    // code to create IndexFile and DictionaryFile...
    ...
    Thread taskOne = new GetNameTask(packOneIndex, packOneDict);
    Thread taskTwo = new GetNameTask(packTwoIndex, packTwoDict);
    taskOne.start();
    taskTwo.start();
}

However, if I run with main method, it works:

// Switch to test with good-old main method.
public static void main(String args[]) {

        // code to create IndexFile and DictionaryFile...
        ...
        Thread taskOne = new GetNameTask(packOneIndex, packOneDict);
        Thread taskTwo = new GetNameTask(packTwoIndex, packTwoDict);
        taskOne.start();
        taskTwo.start();
}

And this is the task:

public class GetNameTask extends Thread {

    public GetNameTask (IndexFile indexFile, DictionaryFile dictFile) {
        this.dictFile = dictFile;
        this.indexFile = indexFile;
    }

    @Override
    public void run() {
        Dictionary dictionary = new DICTDictionary(indexFile, dictFile);
        System.out.println(dictionary.getName());
    }

    private final IndexFile indexFile;
    private final DictionaryFile dictFile;
}

When constructing DICTDictionary, there is a chain of IO operations to get the name of dictionary from the file.

By any chances that running IO code using multithreading does not work with JUnit?

EDIT: I found out how to make it works. Because JUnit executes the tests on single Threads, so I have to join my 2 small threads to JUnit threads to get expected result. So, this works.

@Test
public void testGetNameWithMultithreading() { 

    // code to create IndexFile and DictionaryFile...
    ...
    Thread taskOne = new GetNameTask(packOneIndex, packOneDict);
    Thread taskTwo = new GetNameTask(packTwoIndex, packTwoDict);
    taskOne.start();
    taskTwo.start();
    try {
        taskOne.join();
        taskTwo.join();
    } catch (InteruptedException ie) {
        ie.printStackTrace();
    }
}

Is there any easier way to test multitheading code with JUnit?

Best regards.

Genzer
  • 2,921
  • 2
  • 25
  • 38

2 Answers2

2

Your test method has to block the execution until the Threads are done.

Consider using a ThreadPool. See ExecutorService.awaitTemination for more...

Omnaest
  • 3,096
  • 1
  • 19
  • 18
2

JUnit is notorious for not dealing properly with threads.

I've only been able to get them to work using TestNG. I'd recommend a switch. It should mean little more than a different @Test annotation import and a new JAR in the CLASSPATH.

duffymo
  • 305,152
  • 44
  • 369
  • 561
  • 2
    Yes, all you need to do with TestNG is write your tests the normal way and then tell TestNG to run them in threads in your testng.xml. You can also run individual methods in threads with @Test(threadPoolSize = 10, invocationCount = 10000). http://testng.org – Cedric Beust Aug 06 '11 at 22:22
  • 1
    Cedric Beust is the creator of TestNG, for those who don't know. Great stuff. – duffymo Aug 07 '11 at 15:08