Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/365.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 可以使用JUnit测试多线程吗?_Java_Multithreading_Unit Testing_Junit - Fatal编程技术网

Java 可以使用JUnit测试多线程吗?

Java 可以使用JUnit测试多线程吗?,java,multithreading,unit-testing,junit,Java,Multithreading,Unit Testing,Junit,我有一段代码,其中不同的线程操作HashMap。 我必须同步这段代码。 稍后,我想使用JUnit来测试这一点。 那么,是否可以使用JUnit测试多线程呢? 如果是,请给我举个例子。当然可以,但这并不容易 弗里曼和普赖斯的书中有一个关于这个话题的极好的章节,我可以强烈推荐 我实际上已经这样做了,但只针对简单的多线程场景。基本上,您想要的是将多个线程的访问同步到您的hashmap,或者换句话说,要有一个可预测的顺序,其中一组线程访问hashmap上的内容。您可以构建测试用例,其中每个线程都记录在na

我有一段代码,其中不同的线程操作HashMap。 我必须同步这段代码。 稍后,我想使用JUnit来测试这一点。 那么,是否可以使用JUnit测试多线程呢?
如果是,请给我举个例子。

当然可以,但这并不容易


弗里曼和普赖斯的书中有一个关于这个话题的极好的章节,我可以强烈推荐

我实际上已经这样做了,但只针对简单的多线程场景。基本上,您想要的是将多个线程的访问同步到您的hashmap,或者换句话说,要有一个可预测的顺序,其中一组线程访问hashmap上的内容。您可以构建测试用例,其中每个线程都记录在nanotime中,每次执行某项操作时都有一个唯一的id,然后在这些日志条目上有一个断言(可以保存在memroy中,它们不必输出到实际文件),以检查它们的顺序是否正确

下面是我如何对多个(实际上只有2个)线程访问数据库进行单元测试的示例,以确保它们按照我期望的顺序执行:

@Test
public void testPessimisticLock3_write_blocking() throws Throwable {
    init();
    final ArrayList<String> eventsOrder = new ArrayList<String>();
    Department d = new Department();

    d.setName("d");

    em.getTransaction().begin();
    em.persist(d);
    em.getTransaction().commit();

    id=d.getId();

    em.getTransaction().begin();
    //aquire lock:
    @SuppressWarnings("unused")
    Department dRet1 = em.find(Department.class, d.getId(),LockModeType.PESSIMISTIC_WRITE);
    eventsOrder.add("First transaction got the lock");
    eventsOrder.add("First transaction will sleep for a while...");
    Thread.sleep(1500);

    new Thread(new Runnable() {

        @Override
        public void run() {
            em2.getTransaction().begin();
            //this will wait for the first transaction to release the lock, so that this 2nd transaction can acquire the lock
            eventsOrder.add("Second transaction will now try to get the lock...");
            em2.find(Department.class, id,LockModeType.PESSIMISTIC_WRITE);
            eventsOrder.add("Second transaction got the lock.");
            em2.getTransaction().commit();

            assertEquals("First transaction got the lock",eventsOrder.get(0));
            assertEquals("First transaction will sleep for a while...",eventsOrder.get(1));
            assertEquals("Second transaction will now try to get the lock...",eventsOrder.get(2));
            assertEquals("First transaction woke up and will commit...",eventsOrder.get(3));
            assertEquals("First transaction has commited.",eventsOrder.get(4));
            assertEquals("Second transaction got the lock.",eventsOrder.get(5));
        }
    }).start();

    Thread.sleep(1500);
    eventsOrder.add("First transaction woke up and will commit...");
    em.getTransaction().commit();
    eventsOrder.add("First transaction has commited.");


}