public void batchDeal(List data ,Integer batchNum) {
int totalNum = data.size();
int pageNum = totalNum % batchNum == 0 ? totalNum / batchNum : totalNum / batchNum + 1;
ExecutorService executor = Executors.newFixedThreadPool(pageNum);
try {
CountDownLatch countDownLatch = new CountDownLatch(pageNum);
List subData = null;
int fromIndex, toIndex;
for (int i = 0; i < pageNum; i++) {
fromIndex = i * batchNum;
toIndex = Math.min(totalNum, fromIndex + batchNum);
subData = data.subList(fromIndex, toIndex);
ImportTask task = new ImportTask(subData, countDownLatch);
executor.execute(task);
}
// 主線程必須在啓動其它線程後立即調用CountDownLatch.await()方法,
// 這樣主線程的操作就會在這個方法上阻塞,直到其它線程完成各自的任務。
// 計數器的值等於0時,主線程就能通過await()方法恢復執行自己的任務。
countDownLatch.await();
} catch (Exception e) {
throw new AppException(e, "異常信息!");
} finally {
// 關閉線程池,釋放資源
executor.shutdown();
}
}
class ImportTask implements Runnable {
private List list;
private CountDownLatch countDownLatch;
public ImportTask(List data, CountDownLatch countDownLatch) {
this.list = data;
this.countDownLatch = countDownLatch;
}
@Override
public void run() {
if (null != list) {
// 業務邏輯,例如批量insert或者update
logger.info("現在操作的數據是{}", list);
}
// 發出線程任務完成的信號
countDownLatch.countDown();
}
}
Java 使用線程池分批插入或者更新數據
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.