2011-09-11 65 views
4

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

回答

2

我已经这样做了,但只适用于简单的多线程场景。基本上,你想要的是将多个线程的访问同步到你的散列映射,或者换句话说,有一个可预测的顺序,在散列映射上有一堆线程。您可以构建测试用例,其中每个Thread都记录了纳米级别,并在每次执行某些操作时创建一些唯一的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"); 

// dRet1.setName(“dRet1”);

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."); 


} 
相关问题