您好,登錄后才能下訂單哦!
這篇文章主要介紹“Java多線程怎么批量導入數據”,在日常操作中,相信很多人在Java多線程怎么批量導入數據問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”Java多線程怎么批量導入數據”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!
設計思路
由于場景的特點是讀取快,寫入慢,如果是使用多線程處理,建議是數據寫入部分改造為多線程。而數據讀取可以改造成批量讀取數據。簡單來說就是兩個要點:
批量讀取數據 多線程寫入數據
示例
多線程批量處理最簡單的方案是使用線程池來進行處理,下面會通過一個模擬批量讀取和寫入的服務,以及對這個服務的多線程寫入調用作為示例,展示如何多線程批量數據導入。
模擬服務
import java.util.concurrent.atomic.AtomicLong;/*** 數據批量寫入用的模擬服務** @author RJH* create at 2019-04-01*/public class MockService {/*** 可讀取總數*/private long canReadTotal;/*** 寫入總數*/private AtomicLong writeTotal=new AtomicLong(0);/*** 寫入休眠時間(單位:毫秒)*/private final long sleepTime;/*** 構造方法** @param canReadTotal* @param sleepTime*/public MockService(long canReadTotal, long sleepTime) {this.canReadTotal = canReadTotal;this.sleepTime = sleepTime;}/*** 批量讀取數據接口** @param num* @return*/public synchronized long readData(int num) {long readNum;if (canReadTotal >= num) {canReadTotal -= num;readNum = num;} else {readNum = canReadTotal;canReadTotal = 0;}//System.out.println("read data size:" + readNum);return readNum;}/*** 寫入數據接口*/public void writeData() {try {// 休眠一定時間模擬寫入速度慢Thread.sleep(sleepTime);} catch (InterruptedException e) {e.printStackTrace();}// 寫入總數自增System.out.println("thread:" + Thread.currentThread() + " write data:" + writeTotal.incrementAndGet());}/*** 獲取寫入的總數** @return*/public long getWriteTotal() {return writeTotal.get();}}
批量數據處理器
import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;/*** 基于線程池的多線程批量寫入處理器* @author RJH* create at 2019-04-01*/public class SimpleBatchHandler {private ExecutorService executorService;private MockService service;/*** 每次批量讀取的數據量*/private int batch;/*** 線程個數*/private int threadNum;public SimpleBatchHandler(MockService service, int batch,int threadNum) {this.service = service;this.batch = batch;//使用固定數目的線程池this.executorService = Executors.newFixedThreadPool(threadNum);}/*** 開始處理*/public void startHandle() {// 開始處理的時間long startTime = System.currentTimeMillis();System.out.println("start handle time:" + startTime);long readData;while ((readData = service.readData(batch)) != 0) {// 批量讀取數據,知道讀取不到數據才停止for (long i = 0; i < readData; i++) {executorService.execute(() -> service.writeData());}}// 關閉線程池executorService.shutdown();while (!executorService.isTerminated()) {//等待線程池中的線程執行完}// 結束時間long endTime = System.currentTimeMillis();System.out.println("end handle time:" + endTime);// 總耗時System.out.println("total handle time:" + (endTime - startTime) + "ms");// 寫入總數System.out.println("total write num:" + service.getWriteTotal());}}
測試類
/*** SimpleBatchHandler的測試類* @author RJH* create at 2019-04-01*/public class SimpleBatchHandlerTest {public static void main(String[] args) {// 總數long total=100000;// 休眠時間long sleepTime=100;// 每次拉取的數量int batch=100;// 線程個數int threadNum=16;MockService mockService=new MockService(total,sleepTime);SimpleBatchHandler handler=new SimpleBatchHandler(mockService,batch,threadNum);handler.startHandle();}}
運行結果
start handle time:1554298681755thread:Thread[pool-1-thread-2,5,main] write data:1thread:Thread[pool-1-thread-1,5,main] write data:2...省略部分輸出thread:Thread[pool-1-thread-4,5,main] write data:100000end handle time:1554299330202total handle time:648447mstotal write num:100000
分析
在單線程情況下的執行時間應該為total*sleepTime,即10000000ms,而改造為多線程后執行時間為648447ms。
到此,關于“Java多線程怎么批量導入數據”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。