自定義線程池詳解

自定義線程池

ThreadPoolExecutor executor = new ThreadPoolExecutor(5, 10, 200, TimeUnit.MILLISECONDS, 
				new ArrayBlockingQueue<Runnable>(5));

第一個參數:核心線程池大小,默認創建後就不會銷燬,需要設置allowCoreThreadTimeOut爲true時會銷燬
第二個參數:線程池最大大小
第三個參數:線程池最大空閒時間(線程空閒下來多久自動釋放)
第四個參數:時間單位
第五個參數:線程阻塞隊列

image

  • 對上圖的詳解

1 提交任務到線程池:executor.execute(new Runable());

2 判斷核心線程池大小是否已滿,否,執行任務

3 是,判斷隊列是否已滿,否,進行等待隊列

4 是,判斷最大線程池大小是否已滿,否,執行任務

5 是,執行拒絕策略,對外就是拋出異常

提供的現成可使用的線程池

Executors.newCachedThreadPool(無界線程池,自動線程回收)

Executors.newFixedThreadPool(固定大小的線程池)

Executors.newSingleThreadExecutor(單一後臺線程)

我做過的真實案例-> 線程池應用

  • 場景:數據庫大量數據(百萬級)需要同步至Elasticsearch庫,目前採用的單線程的方式,每次從數據庫中讀取5000條數據同步至Elasticsearch庫,循環n次,直到數據庫讀取不到數據則同步完成。 缺點:此過程需要2小時時間。

  • 改造:需要將同步時間縮短,同步不能使ES崩掉

  • 方案:採用線程池的方式,配置如下:

核心線程池大小爲2 最大線程池大小爲2 線程池最大空閒時間 0秒 隊列大小 1000, 隊列大小的選擇:1000 * 5000 = 500萬 數據不超過5百萬

  • 實現代碼:每同步完成一次需要返回具體插入了ES庫的條數,然後實現累加可算出本次同步一共同步了多少條,JDK提供了Future對象

    do {
    	List<JSONObject> list = cilSettOracleMapper.findCilSettByDate(sysDate, page * SIZE, (page + 1) * SIZE);
    	if(list != null && list.size() > 0){
    		Future<Long> future = ThreadManager.executorService.submit(new Callable<Long>() {
    			@Override
    			public Long call(){
    				log.debug("線程名:" + Thread.currentThread().getName() + "-->" + bulkRequestSize);
    				return ESClient.getESClient().indexCilSettOracle(request, list, scanTransService, merInfoMapper, bulkRequestSize);
    			}
    		});
    		futrueList.add(future);
    	}else{
    		break;
    	}
    	log.info("indexCilSett page:" + page + ",bulkRequestSize: " + bulkRequestSize);
    	page++;
    } while (true);
    
    Long futureRequestSize = 0L;
    for(Future<Long> f : futrueList) {
    	try {
    		futureRequestSize += f.get();
    	} catch (InterruptedException | ExecutionException e) {
    		log.error("執行Future的get方法發生異常", e);
    	}
    }
    
  • 上述注意部分:第一次接觸Future類,當時直接在循環裏調用future.get()方法獲取數據,發現線程是一個一個按照順序去執行,後來瞭解到get()方法會阻塞線程,於是有了上述的先將Future對象有list存起來,然後循環拿結果。

  • Future類講解的比較好的:https://www.cnblogs.com/dolphin0520/p/3949310.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章