温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

Java多线程怎么批量导入数据

发布时间:2021-11-20 11:48:48 来源:亿速云 阅读:606 作者:iii 栏目:编程语言

这篇文章主要介绍“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多线程怎么批量导入数据”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注亿速云网站,小编会继续努力为大家带来更多实用的文章!

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI