1.多線程配置
/**
* 配置線程池參數 根據自己需要配置
*/
private static ExecutorService cachedThreadPool = new ThreadPoolExecutor(0,
Integer.MAX_VALUE,
60L,
TimeUnit.SECONDS,
new SynchronousQueue<Runnable>(),
namedThreadFactory);
2.線程調用方法
/**
* 線程池調用方法
*
* @param param
*/
public void run(BatchStartFlowParam param) {
cachedThreadPool.execute(new SendMsg(param));
}
3.發送消息類
/**
* 發送消息類
*
* @param param
*/
public class SendMsg implements Runnable {
private BatchStartFlowParam param;
public SendMsg(BatchStartFlowParam param) {
this.param = param;
}
@Autowired
private StartFlowService startFlowService;
@Override
public void run() {
log.info(Thread.currentThread().getName());
startFlowService.startFlowList(param);
}
}
如下圖:startFlowService 報空指針異常,並沒有通過 @Autowired 注入進來。
4.問題描述及解決方法
單獨開的線程中不能使用 @Autowired 注入對象從而導致 java.lang.NullPointerException,而是應該從 Spring 容器中獲取該對象進行引用。
代碼修改如下,只需修改第三步的發送消息類如下
public class SendMsg implements Runnable {
private BatchStartFlowParam param;
public SendMsg(BatchStartFlowParam param) {
this.param = param;
}
private static StartFlowService startFlowService;
static {
//從 Spring 容器中 獲取 startFlowService 對象
startFlowService = SpringContext.getBean(StartFlowService.class);
}
@Override
public void run() {
log.info(Thread.currentThread().getName());
startFlowService.startFlowList(param);
}
}
解決方案2
還有一種解決方案如下:
將上述的線程調用方法修改如下,只需修改上面第二步的線程調用方法,新增一個發送消息方法 sendMsg();並修改線程調用發送消息的方法,如下所示。
@Autowired
private StartFlowService startFlowService;
/**
* 線程池調用方法
*
* @param param
*/
public void run(BatchStartFlowParam param) {
//cachedThreadPool.execute(new SendMsg(param));
cachedThreadPool.execute(() -> {
sendMsg(param);
});
}
/**
* 發送消息
*
* @param param
*/
public void sendMsg(BatchStartFlowParam param) {
System.out.println(Thread.currentThread().getName());
System.out.println(JSONObject.toJSONString(param));
startFlowService.startFlowList(param);
}