【问题标题】:Test multithreaded code with JUnit - strange behavior使用 JUnit 测试多线程代码 - 奇怪的行为
【发布时间】:2011-08-06 17:11:53
【问题描述】:

我是 Java 并发的新手。我用 Junit 测试了我的一些代码,但结果很奇怪。下面的代码 sn-p 虽然成功执行,但当我使用 JUnit (Eclipse) 运行它时,它不会向控制台写入任何内容。

@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();
}

但是,如果我使用 main 方法运行,它可以工作:

// 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();
}

这是任务:

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;
}

在构造DICTDictionary时,有一个IO操作链从文件中获取字典名。

有没有可能使用多线程运行 IO 代码不适用于 JUnit?

编辑:我发现了如何让它工作。因为 JUnit 在单个线程上执行测试,所以我必须将我的 2 个小线程加入 JUnit 线程以获得预期的结果。所以,这行得通。

@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();
    }
}

有没有更简单的方法来使用 JUnit 测试多标题代码?

最好的问候。

【问题讨论】:

标签: java multithreading junit io


【解决方案1】:

您的测试方法必须阻止执行,直到线程完成。

考虑使用线程池。更多信息请参见ExecutorService.awaitTemination...

【讨论】:

    【解决方案2】:

    JUnit 因不能正确处理线程而臭名昭著。

    我只能使用 TestNG 让它们工作。我会推荐一个开关。它应该意味着不同的@Test 注释导入和 CLASSPATH 中的新 JAR。

    【讨论】:

    • 是的,您对 TestNG 所要做的就是以正常方式编写测试,然后告诉 TestNG 在 testng.xml 中的线程中运行它们。您还可以使用 @Test(threadPoolSize = 10, invocationCount = 10000) 在线程中运行单个方法。 testng.org
    • Cedric Beust 是 TestNG 的创建者,对于那些不知道的人来说。很棒的东西。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-04
    • 2015-01-07
    • 1970-01-01
    • 2017-12-06
    相关资源
    最近更新 更多