使用多线程时,普通类调用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);
}

 

posted @ 2020-04-22 18:22  明天,你好啊  阅读(4636)  评论(0编辑  收藏  举报