最近做项目过程中,有需要用到多线程这方面的知识,对于我这个小白,属实是查了很多资料,原理什么的,网上很多,这篇只讲我当前遇到的问题及解决。
在线程中发现,若在线程类中去注入Bean实例,会报空指针异常,为这个问题整整搞了半天,原谅我内心纯洁,纯洁到什么都没有。。。
看视图把:
import com.haohuo.beans.User;
import com.haohuo.mapper.UserMapper;
import com.haohuo.util.SpringUtil;
import com.haohuo.ztest.ThreadTest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import java.util.List;
/**
* @author zhangpk
*/
public class ThreadUser extends Thread {
private final int index;
private List<User> list;
@Autowired
private UserMapper mapper;
public ThreadUser(int i , List<User> userList){
this.index = i;
this.list = userList;
}
@Override
public void run() {
try {
User user = list.get(index);
userMapper.updateUserState(user);
log.info("修改到第"+index+"条!此线程:"+Thread.currentThread().getName());
Thread.sleep((int)(Math.random()*1000));
} catch (InterruptedException e) {
e.printStackTrace();
log.error("failed");
} catch (Exception e){
e.printStackTrace();
log.error("failed");
}
}
}
控制台信息:
2018-12-28 11:33:04,823 [pool-1-thread-70] ERROR com.haohuo.service.ThreadUser - 报错了啊啊啊啊啊啊啊
java.lang.NullPointerException: null
针对这种情况,就是userMapper在调用该线程时,由于是在线程类中,spring默认不把它当为Bean来注入,其实网上很多解决方案,比如手动实现把bean注入到spring中,我这边没有那么解决,最终处理是把UserMapper这个bean放到线程类外注入,也就是调用方注入,之后传入,问题解决。
package com.haohuo.service;
import com.haohuo.beans.User;
import com.haohuo.mapper.UserMapper;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.List;
/**
* @author zhangpeike
* @date 15:59 2018/12/27
*/
@Slf4j
public class ThreadUser extends Thread {
private final int index;
private List<User> list;
private UserMapper userMapper;
public ThreadUser(int i , List<User> userList, UserMapper mapper){
this.index = i;
this.list = userList;
this.userMapper = mapper;
}
@Override
public void run() {
try {
User user = list.get(index);
userMapper.updateUserState(user);
log.info("修改到第"+index+"条!此线程:"+Thread.currentThread().getName());
Thread.sleep((int)(Math.random()*1000));
} catch (InterruptedException e) {
e.printStackTrace();
log.error("报错了啊啊啊啊啊啊啊", e);
} catch (Exception e){
e.printStackTrace();
log.error("报错了啊啊啊啊啊啊啊" ,e);
}
}
}