使用多線程時,普通類調用service層方法報空指針異常


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);
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM