在一次测试类过程中。使用了多线程测试数据库数据的安全性。导致了走不到mybatis。
代码如下。
@Test
public void getTableId() throws InterruptedException {
ExecutorService executorService = Executors.newFixedThreadPool(1000);
for (int i = 1; i < 1000; i++) {
int j = i;
executorService.execute(() -> {
System.out.println(j);
SysTableKeyServiceImpl bean = SpringUtils.getBean(SysTableKeyServiceImpl.class);
bean.getTableId("300030500000006", "shift_seqid");
});
}
}
导致问题的原因是,junit身为主线程,execute是子线程,当for循环执行完毕后,主线程直接销毁了,导致execute的子线程也跟着销毁了,导致getTabledId 的查询失败了。
java中java.util.concurrent这个包提供了CountDownLatch类来解决这种并发问题。代码如下。
private final CountDownLatch countDownLatch = new CountDownLatch(999);
@Test
public void getTableId() throws InterruptedException {
ExecutorService executorService = Executors.newFixedThreadPool(1000);
// List<String> nos = new ArrayList<>();
for (int i = 1; i < 1000; i++) {
int j = i;
executorService.execute(() -> {
SysTableKeyServiceImpl bean = SpringUtils.getBean(SysTableKeyServiceImpl.class);
System.out.println(j);
String shift_seqid = bean.getTableId("300030500000006", "shift_seqid");
countDownLatch.countDown();
});
}
countDownLatch.await();
}
CountDownLatch给定了线程的执行顺序,countDownLatch.await()表示主线程等待执行。countDownLatch.countDown(),即线程执行完毕。当所有子线程执行完毕后,即countDownLatch到0的时候,主线程关闭。到此解决了此类问题。