最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java多線程批量數(shù)據(jù)導入的方法詳解

 更新時間:2019年06月05日 14:47:19   作者:不言  
這篇文章主要介紹了Java多線程批量數(shù)據(jù)導入的方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,下面小編和大家來一起學習下吧

前言:

當遇到大量數(shù)據(jù)導入時,為了提高處理的速度,可以選擇使用多線程來批量處理這些處理。常見的場景有:

  • 大文件導入數(shù)據(jù)庫(這個文件不一定是標準的CSV可導入文件或者需要在內(nèi)存中經(jīng)過一定的處理)
  • 數(shù)據(jù)同步(從第三方接口拉取數(shù)據(jù)處理后寫入自己的數(shù)據(jù)庫)

以上的場景有一個共性,這類數(shù)據(jù)導入的場景簡單來說就是將數(shù)據(jù)從一個數(shù)據(jù)源移動到另外一個數(shù)據(jù)源,而其中必定可以分為兩步

  • 數(shù)據(jù)讀?。簭臄?shù)據(jù)源讀取數(shù)據(jù)到內(nèi)存
  • 數(shù)據(jù)寫入:將內(nèi)存中的數(shù)據(jù)寫入到另外一個數(shù)據(jù)源,可能存在數(shù)據(jù)處理

而且根據(jù)讀取的速度一般會比數(shù)據(jù)寫入的速度快很多,即讀取快,寫入慢。

設計思路

由于場景的特點是讀取快,寫入慢,如果是使用多線程處理,建議是數(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:1554298681755
thread:Thread[pool-1-thread-2,5,main] write data:1
thread:Thread[pool-1-thread-1,5,main] write data:2
...省略部分輸出
thread:Thread[pool-1-thread-4,5,main] write data:100000
end handle time:1554299330202
total handle time:648447ms
total write num:100000

分析

在單線程情況下的執(zhí)行時間應該為total*sleepTime,即10000000ms,而改造為多線程后執(zhí)行時間為648447ms。

以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

相關文章

  • Spring Boot 中的 CommandLineRunner 原理及使用示例解析

    Spring Boot 中的 CommandLineRunner 原理及使用示例

    CommandLineRunner 是 Spring Boot 提供的一個非常有用的接口,可以幫助你在應用程序啟動后執(zhí)行初始化任務,本文通過多個示例詳細介紹了如何在實際項目中使用 CommandLineRunner,感興趣的朋友一起看看吧
    2025-04-04
  • MyBatis 中 ${}和 #{}的正確使用方法(千萬不要亂用)

    MyBatis 中 ${}和 #{}的正確使用方法(千萬不要亂用)

    這篇文章主要介紹了MyBatis 中 ${}和 #{}的正確使用方法,本文給大家提到了MyBatis 中 ${}和 #{}的區(qū)別,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-07-07
  • Java面向對象基礎詳解

    Java面向對象基礎詳解

    這篇文章主要介紹了JJava面向對象的基礎,文中有非常詳細的代碼示例,對正在學習java基礎的小伙伴們有很好的幫助,需要的朋友可以參考下
    2021-10-10
  • java集合Collection實現(xiàn)類解析ArrayList?LinkedList及Vector

    java集合Collection實現(xiàn)類解析ArrayList?LinkedList及Vector

    這篇文章主要為大家介紹了java集合Collection實現(xiàn)類解析ArrayList?LinkedList及Vector,有需要的朋友可以借鑒參考下,希望能夠有所幫助
    2022-03-03
  • java對接支付寶支付項目的實戰(zhàn)記錄

    java對接支付寶支付項目的實戰(zhàn)記錄

    最近公司有一個需求是接入第三方支付(微信&支付寶),我接到了支付寶支付,所以下面這篇文章主要給大家介紹了關于java對接支付寶支付項目的相關資料,需要的朋友可以參考下
    2022-06-06
  • 舉例說明Java設計模式編程中ISP接口隔離原則的使用

    舉例說明Java設計模式編程中ISP接口隔離原則的使用

    這篇文章主要介紹了Java設計模式編程中ISP接口隔離原則的使用,接口隔離原則主張一個類對另外一個類的依賴性應當是建立在最小的接口上,需要的朋友可以參考下
    2016-02-02
  • Jmeter自定義函數(shù)base64加密實現(xiàn)過程解析

    Jmeter自定義函數(shù)base64加密實現(xiàn)過程解析

    這篇文章主要介紹了Jmeter自定義函數(shù)base64加密實現(xiàn)過程解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-07-07
  • Java獲取時間年、月、日的方法

    Java獲取時間年、月、日的方法

    這篇文章主要介紹了Java獲取時間年、月、日的方法,涉及java時間操作的相關技巧,需要的朋友可以參考下
    2015-05-05
  • Springboot+redis+Interceptor+自定義annotation實現(xiàn)接口自動冪等

    Springboot+redis+Interceptor+自定義annotation實現(xiàn)接口自動冪等

    本篇文章給大家介紹了使用springboot和攔截器、redis來優(yōu)雅的實現(xiàn)接口冪等,對于冪等在實際的開發(fā)過程中是十分重要的,因為一個接口可能會被無數(shù)的客戶端調用,如何保證其不影響后臺的業(yè)務處理,如何保證其只影響數(shù)據(jù)一次是非常重要的,感興趣的朋友跟隨小編一起看看吧
    2019-07-07
  • maven項目下solr和spring的整合配置詳解

    maven項目下solr和spring的整合配置詳解

    這篇文章主要介紹了maven項目下solr和spring的整合配置詳解,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-11-11

最新評論

扎鲁特旗| 噶尔县| 龙里县| 工布江达县| 丰镇市| 连南| 交城县| 中卫市| 洛南县| 余庆县| 邓州市| 丰城市| 神农架林区| 柯坪县| 晋江市| 崇文区| 佛山市| 安西县| 霞浦县| 韩城市| 新晃| 万荣县| 民县| 北流市| 青神县| 澳门| 利辛县| 河池市| 洪湖市| 仙桃市| 龙口市| 武乡县| 镇原县| 封开县| 镶黄旗| 阳东县| 彰化市| 内黄县| 侯马市| 左权县| 泰宁县|