在實作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;
}
}