在实现Java多线程的时候,发现使用@Autowired或者@Resource依赖注入的类都会报空指针异常(NullPointerException)。
原因:
spring的声明周期,在工程启动时,并不会检测到线程类中的bean对其进行管理和注入;
解决方法:
1、 手动管理
private UserDao userDao = new UserDaoImpl();
如果是使用这种方式,缺点是每一次创建线程,都会重新创建一次实现类,资源过度消耗;(建议自行实现单例模式\工厂模式 自行管理;麻烦,不建议使用此种方式)
2、参数带入
在引用线程类的地方依赖注入所需的bean类,然后在线程的构造方法中,以参数的形式将先关bean类携带到线程中进行逻辑处理;
代码实例:
Service层:
public class UserServiceImpl implements UserService {
@Autowired
UserDao userDao;
private void test() {
//创建线程任务时,直接将所需依赖注入的bean携带进子线程中
ThreadTask task = new ThreadTask(userDao);
ThreadPool.getThreadPool().execute(task);
}
}
子线程任务类:
/**
* 子线程任务
* @author Kellan_Song
* @createTime 2019年4月16日
*/
public class ThreadTask implements Runnable {
private UserDao userDao;
public ThreadTask(UserDao userDao) {
this.userDao = userDao;
}
@Overried
public void run() {
System.out.println(userDao.getHashCode());
}
}
线程池
/**
* 使用单例模式实现 线程池
* @author Kellan_Song
* @createTime 2019年4月16日
*/
public class ThreadPool {
private static ThreadPoolTaskExecutor threadPoolTaskExecutor = null;
public static ThreadPoolTaskExecutor getThreadPool() {
if (threadPoolTaskExecutor == null) {
synchronized (ThreadPool.class) {
if (threadPoolTaskExecutor == null) {
threadPoolTaskExecutor = new ThreadPoolTaskExecutor();
//最小线程数
threadPoolTaskExecutor.setCorePoolSize(500);
//最大线程数
threadPoolTaskExecutor.setMaxPoolSize(2000);
//空闲线程存活时间
threadPoolTaskExecutor.setKeepAliveSeconds(200);
//队列中最大线程
threadPoolTaskExecutor.setQueueCapacity(2000);
//初始化
threadPoolTaskExecutor.initialize();
}
}
}
return threadPoolTaskExecutor;
}
}