Junit多线程的坑
关于使用Junit测试多线程的坑
先看代码:
@Test
public void testEhCache() throws InterruptedException {Thread putThread = new Thread(() -> {EhCacheUtil cacheUtil = EhCacheUtil.getInstance();cacheUtil.preConfigureCache("shortTermCache", 5L);cacheUtil.putToCache("shortTermCache", "tempData", "临时数据");});putThread.start();// 为确保 putThread 放数据成功,让主线程睡眠1秒后再启动获取数据的线程Thread.sleep(1000);Thread getThread= new Thread(() -> {EhCacheUtil cacheUtil = EhCacheUtil.getInstance();String fromCache = cacheUtil.getFromCache("shortTermCache", "tempData");System.out.println("获取数据:"+fromCache);});getThread.start();
}
上面的代码中,EhCacheUtil是自己写的一个EhCache缓存的工具类,线程putThread用于向缓存中放置数据,getThread从缓存中取出数据
大坑
putThread线程放数据成功,但是getThread线程执行到 String fromCache = cacheUtil.getFromCache(“shortTermCache”, “tempData”); 从缓存中获取数据时,就整个程序结束了,代码System.out.println(“获取数据:”+fromCache);都不会执行,控制台也不会输出日志。也没有任何报错
原因
从缓存中获取数据时,需要的时间比主线程运行时间长,因此在主线程结束时,子线程getThread获取数据还未完成,就被强制退出,因为Junit 4 和 5 的默认行为是:当测试方法(主线程)执行完毕后,测试进程会退出,此时所有未完成的子线程可能被强制终止(取决于 JVM 实现)。即使子线程仍在运行,它们的输出或后续操作可能无法完整执行
解决方法
1、在开启线程后,立即调用join方法,即主线程会等待子线程执行完毕后再消亡
...... 前置逻辑
getThread.start();
getThread.join();
...... 后续逻辑
2、使用main方法来测试,但是要注意不要设置子线程为守护线程