這篇文章主要介紹“Java多線程怎么批量導入數(shù)據(jù)”,在日常操作中,相信很多人在Java多線程怎么批量導入數(shù)據(jù)問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”Java多線程怎么批量導入數(shù)據(jù)”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!
創(chuàng)新互聯(lián)技術團隊10多年來致力于為客戶提供成都做網(wǎng)站、成都網(wǎng)站建設、品牌網(wǎng)站制作、網(wǎng)絡營銷推廣、搜索引擎SEO優(yōu)化等服務。經(jīng)過多年發(fā)展,公司擁有經(jīng)驗豐富的技術團隊,先后服務、推廣了超過千家網(wǎng)站,包括各類中小企業(yè)、企事單位、高校等機構單位。
設計思路
由于場景的特點是讀取快,寫入慢,如果是使用多線程處理,建議是數(shù)據(jù)寫入部分改造為多線程。而數(shù)據(jù)讀取可以改造成批量讀取數(shù)據(jù)。簡單來說就是兩個要點:
批量讀取數(shù)據(jù) 多線程寫入數(shù)據(jù)
示例
多線程批量處理最簡單的方案是使用線程池來進行處理,下面會通過一個模擬批量讀取和寫入的服務,以及對這個服務的多線程寫入調用作為示例,展示如何多線程批量數(shù)據(jù)導入。
模擬服務
import java.util.concurrent.atomic.AtomicLong;/*** 數(shù)據(jù)批量寫入用的模擬服務** @author RJH* create at 2019-04-01*/public class MockService {/*** 可讀取總數(shù)*/private long canReadTotal;/*** 寫入總數(shù)*/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;}/*** 批量讀取數(shù)據(jù)接口** @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;}/*** 寫入數(shù)據(jù)接口*/public void writeData() {try {// 休眠一定時間模擬寫入速度慢Thread.sleep(sleepTime);} catch (InterruptedException e) {e.printStackTrace();}// 寫入總數(shù)自增System.out.println("thread:" + Thread.currentThread() + " write data:" + writeTotal.incrementAndGet());}/*** 獲取寫入的總數(shù)** @return*/public long getWriteTotal() {return writeTotal.get();}}
批量數(shù)據(jù)處理器
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;/*** 每次批量讀取的數(shù)據(jù)量*/private int batch;/*** 線程個數(shù)*/private int threadNum;public SimpleBatchHandler(MockService service, int batch,int threadNum) {this.service = service;this.batch = batch;//使用固定數(shù)目的線程池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) {// 批量讀取數(shù)據(jù),知道讀取不到數(shù)據(jù)才停止for (long i = 0; i < readData; i++) {executorService.execute(() -> service.writeData());}}// 關閉線程池executorService.shutdown();while (!executorService.isTerminated()) {//等待線程池中的線程執(zhí)行完}// 結束時間long endTime = System.currentTimeMillis();System.out.println("end handle time:" + endTime);// 總耗時System.out.println("total handle time:" + (endTime - startTime) + "ms");// 寫入總數(shù)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) {// 總數(shù)long total=100000;// 休眠時間long sleepTime=100;// 每次拉取的數(shù)量int batch=100;// 線程個數(shù)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
分析
在單線程情況下的執(zhí)行時間應該為total*sleepTime,即10000000ms,而改造為多線程后執(zhí)行時間為648447ms。
到此,關于“Java多線程怎么批量導入數(shù)據(jù)”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續(xù)學習更多相關知識,請繼續(xù)關注創(chuàng)新互聯(lián)網(wǎng)站,小編會繼續(xù)努力為大家?guī)砀鄬嵱玫奈恼拢?/p>
分享題目:Java多線程怎么批量導入數(shù)據(jù)
網(wǎng)頁網(wǎng)址:http://weahome.cn/article/ihhdgj.html