Java 使用多个并发线程在中执行一组测试方法

Java 使用多个并发线程在中执行一组测试方法,java,multithreading,junit,concurrency,Java,Multithreading,Junit,Concurrency,如果以10个并发线程的形式运行这3个方法,那么基于JUnit的代码是什么呢 @RunWith(SpringJUnit4ClassRunner.class @SpringBootTest public class TestClass { @Test public void readFromDBOneRecord(){ try { dbService.findOneByID("1"); } catch (Exception error

如果以10个并发线程的形式运行这3个方法,那么基于JUnit的代码是什么呢

@RunWith(SpringJUnit4ClassRunner.class
@SpringBootTest
public class TestClass {


    @Test
    public void readFromDBOneRecord(){
       try {
         dbService.findOneByID("1");
       } catch (Exception error) {
             Assert.fail("Unexpected error occured .");
       }
    }

    @Test
    public void writeToDBOneRecord(){
       try {
             dbService.save(entity.builder()
                            .setID("1").setName("John").build())
       } catch (Exception error) {
             Assert.fail("Unexpected error occured .");
       }
    }

    @Test
    public void deleteDbRecord(){
       try {
          dbService.delete("1");
       } catch (Exception error) {
             Assert.fail("Unexpected error occured .");
       }
    }
}
在某些情况下,某些方法会抛出异常。类似于在写入数据库记录之前执行的
delete
。 因此,每个方法的顺序仅为3个线程,例如:

OperationNr|| OperationName || [ThreadNr/total threads per method]OperationType

     1.        write        [2/3]w
     2.        read         [1/3]r
     3.        read         [3/3]r
     4.        delete       [2/3]d
     5.        read         [2/3]r
     6.        delete       [3/3]d ->exception no record
     7.        write        [1/3]w
     8.        write        [3/3]w ->exception record already present
     9.        delete       [1/3]d

在10个并发线程(总共30个)中执行这3个测试方法的代码是什么?

由于您希望并行执行所有操作,我将混合所有操作并依靠
倒计时闩锁
实例同步线程,如下所示:

@Test
public void testMultiThreading() throws Exception {
    // Total of reader threads
    int reader = 5;
    // Total of writer threads
    int writer = 3;
    // Total of remover threads
    int remover = 1;
    // CountDownLatch used to release all the threads at the same time
    final CountDownLatch startSignal = new CountDownLatch(1);
    // CountDownLatch used to be notified when all threads did their task
    final CountDownLatch doneSignal = new CountDownLatch(reader + writer + remover);
    // List in which we collect all the errors
    final List<Exception> errors = Collections.synchronizedList(new ArrayList<>());
    // Create all the reader threads and start them
    for (int i = 0; i < reader; i++) {
        Thread thread = new Thread() {
            public void run() {
                try {
                    startSignal.await();
                    dbService.findOneByID("1");
                } catch (Exception e) {
                    errors.add(e);
                } finally {
                    doneSignal.countDown();
                }
            }
        };
        thread.start();
    }
    // Create all the writer threads and start them
    for (int i = 0; i < writer; i++) {
        Thread thread = new Thread() {
            public void run() {
                try {
                    startSignal.await();
                    dbService.save(entity.builder()
                        .setID("1").setName("John").build());
                } catch (Exception e) {
                    errors.add(e);
                } finally {
                    doneSignal.countDown();
                }
            }
        };
        thread.start();
    }
    // Create all the remover threads and start them
    for (int i = 0; i < remover; i++) {
        Thread thread = new Thread() {
            public void run() {
                try {
                    startSignal.await();
                    dbService.delete("1");
                } catch (Exception e) {
                    errors.add(e);
                } finally {
                    doneSignal.countDown();
                }
            }
        };
        thread.start();
    }
    // Release the threads
    startSignal.countDown();
    // Wait until all threads did their task
    doneSignal.await();
    // If an error has been collected, print the stack trace and throws the
    // first error to make the test fail
    if (!errors.isEmpty()) {
        for (Exception e : errors) {
            e.printStackTrace();
        }
        throw errors.get(0);
    }
}
@测试
public void testMultiThreading()引发异常{
//读卡器线程总数
int读取器=5;
//写入线程总数
int writer=3;
//拆卸器螺纹总数
int-remover=1;
//用于同时释放所有线程的倒计时闩锁
最终倒计时闩锁启动信号=新倒计时闩锁(1);
//CountDownLatch过去在所有线程执行任务时都会收到通知
final CountDownLatch doneSignal=新的CountDownLatch(读卡器+写卡器+删除器);
//收集所有错误的列表
最终列表错误=Collections.synchronizedList(新的ArrayList());
//创建所有读卡器线程并启动它们
for(int i=0;i

NB:如果您希望一个给定的单元测试由多个并发线程执行,请查看,但它不允许您将它们混合在一起,因为您希望实现

您希望并行执行所有操作吗?所有线程使用完全相同的ID,此处为1?我希望每个测试方法都在定义的线程数中执行。例如,我想让5个并发读线程与3个并发写线程同时执行。因此,两个测试方法由8个线程并行执行。“[2/3]”是线程ID-它表示一种类型的3个线程中有2个线程,因此它在eg read方法中是唯一的。我已经进行了编辑并添加了一个字母,表示每个线程ID属于特定的方法类型(hrer read、write、delete)这不是JUnit,而是一个有趣的解决方案。在使用它时,我如何检查每个线程
bookService
方法与线程id连接的结果?我不确定我是否理解您的问题,如果您想测试像findOneByID这样的方法的结果,您可以在调用方法后直接在run方法中添加断言,如果断言失败,将引发异常,然后测试将失败。是的,我知道这不是一个真正的单元测试,但是你想要实现的不是一个真正的单元测试。我认为你在方法上是对的。是的,它实际上不是一个单元测试用例。我刚刚发现了一些
aven-surefire插件
运行并发测试的可能性,如果回答了这个问题,我将发布这些测试。感谢您的解决方案-当然是投票通过的。AFAIK maven surefire插件只允许您并行运行测试。如果您希望一个给定的单元测试由多个并发线程执行,请查看contiperf,但它不允许您将它们混合使用。您是否查看过contiperf以在单独的线程中多次运行单个测试用例?