天天看點

Java多線程學習:子線程中無法使用Spring的依賴注入

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