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