java多线程:ExecutorService多线程实例(六)
来源:互联网 发布:vscode markdown 编辑:程序博客网 时间:2024/06/05 02:32
了解了ExecutorService,现在就来看下具体业务的具体应用。
解决大量数据同时插入数据库的多线程实现,解决其性能问题:
1、线程池
package com.akk.thread;import java.util.ArrayList;import java.util.Collection;import java.util.List;import java.util.concurrent.Callable;import java.util.concurrent.ExecutionException;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.Future;import java.util.concurrent.TimeUnit;import java.util.concurrent.TimeoutException;/** * * Description: 线程池 */public class ThreadUtil { private ExecutorService pool; private int max; private final static int DEFAULT_TIMEOUT = 520; public ThreadUtil(int max) { this.max = max; pool = Executors.newFixedThreadPool(max); } /** * * <p>Descrption: 执行单线程</p> * @return void * @param cmd */ public void execute(Runnable cmd) throws Exception { pool.execute(cmd); } /** * * <p>Descrption: 执行批量无返回</p> * @return void * @param cmd */ public void executeNotWait(Collection<? extends Callable<?>> tasks) throws Exception { //pool.invokeAll(tasks); } /** * * <p>Descrption: 批量执行返回</p> * @return List<T> * @param tasks * @return * @throws InterruptedException * @throws ExecutionException * @throws TimeoutException */ public <T> List<T> execute(Collection<? extends Callable<T>> tasks) throws InterruptedException, ExecutionException, TimeoutException { return execute(tasks, DEFAULT_TIMEOUT); } /** * 设置超时时间 * @param tasks * @param timeout * @return * @throws InterruptedException * @throws ExecutionException * @throws TimeoutException */ public <T> List<T> execute(Collection<? extends Callable<T>> tasks, int timeout) throws InterruptedException, ExecutionException, TimeoutException { List<T> results = new ArrayList<T>(tasks.size()); List<Future<T>> futures = pool.invokeAll(tasks); for (Future<T> future : futures) { results.add(future.get(timeout, TimeUnit.SECONDS)); } return results; } public int getMax() { return max; } }
2、批量列表分批迭代器
package com.akk.thread;import java.util.Iterator;import java.util.List;/** * 批量列表分批迭代器 */public class BatchIterator<T> implements Iterator<List<T>> { private int batchSize; private List<T> list; private int start; private int end; private int pageCount; /** * 新建分批迭代器 * * @param list 要分批的原始列 * @param size 要分批的每批最大数量 */ public BatchIterator(List<T> list, int size){ this.batchSize = size; this.list = list; this.start = 0; this.end += this.batchSize; if (this.end > list.size()) { this.end = list.size(); } this.pageCount = 0; } @Override public boolean hasNext() { return start < list.size(); } @Override public List<T> next() { List<T> resultList = list.subList(start, end); start = end; end += batchSize; if (end > list.size()) { end = list.size(); } ++ pageCount; return resultList; } /** * Gets start. * * @return the start */ public int getStart() { return start; } /** * Gets end. * * @return the end */ public int getEnd() { return end; } /** * Gets batch size. * * @return the batch size */ public int getBatchSize() { return batchSize; } /** * Gets page count. * * @return the page count */ public int getPageCount() { return pageCount; }@Overridepublic void remove() {// TODO Auto-generated method stub}}
3、数据库批量操作时的分批工具
package com.akk.thread;import java.util.ArrayList;import java.util.Iterator;import java.util.List;/** * 数据库批量操作时的分批工具 */public class BatchUtil { /** * 获取分批的List * @param list 原始待分批的列 * @param size 每批最大数量 * @return the batch list */ public static <T> List<List<T>> getBatchList(List<T> list, int size) { List<List<T>> resultList = new ArrayList<List<T>>(); int resultSize = 0; int tmp = 0; while (resultSize < list.size()) { tmp += size; if (tmp > list.size()) { tmp = list.size(); } resultList.add(list.subList(resultSize, tmp)); resultSize = tmp; } return resultList; } /** * 分批批量执行函数式 * 不对返回值进行处理 * 例如: * <pre>{@code * BatchUtil.batchVoidListExecute( * 3, * list -> System.out.print(list.size() + " "), * Lists.newArrayList(1,2,3,4,5,6,7)); * }</pre> * 结果是3 3 1 * @param size 每批最大数量 * @param voidListExt 可以批量执行的函数式,参数是T的List * @param list 原始列 * @param <T> 批量的单位实体类型 */ public static <T> void batchVoidListExecute(int size, VoidListExt<T> voidListExt, List<T> list) { if (list.isEmpty()) { return; } Iterator<List<T>> iterator = new BatchIterator<>(list, size); while (iterator.hasNext()) { voidListExt.execute(iterator.next()); } } /** * 与batchVoidListExecute相同 * 可以用返回值为List的函数式,执行后将返回List拼接为返回值 * @param size * @param listListExt * @param list * @param <T> * @param <S> * @return */ public static <T, S> List<S> batchListListExecute(int size, ListListExt<T, S> listListExt, List<T> list) { Iterator<List<T>> iterator = new BatchIterator<>(list, size); List<S> resultList = new ArrayList<>(); while (iterator.hasNext()) { resultList.addAll(listListExt.execute(iterator.next())); } return resultList; } /** * 与batchVoidListExecute相同 * 可以用返回值为List的函数式,执行后将返回List拼接为返回值 * @param size * @param intListExt * @param list * @param <T> * @return */ public static <T> int batchIntListExecute(int size, IntListExt<T> intListExt, List<T> list) { Iterator<List<T>> iterator = new BatchIterator<>(list, size); int result = 0; while (iterator.hasNext()){ result += intListExt.execute(iterator.next()); } return result; } /** * <p>Description: * 与batchVoidListExecute相同 * 可以自定义返回值类型,然后通过自定义收集函数式来收集结果 * </p> * @param <T> the type parameter * @param <S> the type parameter * @param <R> the type parameter * @param size the size * @param commonListExt the common list ext * @param resultCollector the result collector * @param list the list * @param result the result 用collector将结果收集到其中 * @return the r */ public static <T,S,R> R batchCommonListExecute(int size, CommonListExt<T, S> commonListExt, ResultCollector<S,R> resultCollector, List<T> list, R result) { Iterator<List<T>> iterator = new BatchIterator<>(list, size); while (iterator.hasNext()) { S s = commonListExt.execute(iterator.next()); resultCollector.collect(s, result); } return result; } /** * 参数是List返回值为空的函数式 * @param <T> */// @FunctionalInterface public interface VoidListExt<T> { void execute(List<T> list); } /** * 参数是List返回值也是List的函数式 * @param <T> * @param <S> */// @FunctionalInterface public interface ListListExt<T, S> { List<S> execute(List<T> list); } /** * 参数是List返回值是int的函数式 * @param <T> */// @FunctionalInterface public interface IntListExt<T> { int execute(List<T> list); } /** * 参数是List自定义返回值的函数式 * @param <T> * @param <S> */// @FunctionalInterface public interface CommonListExt<T, S> { S execute(List<T> list); } /** * 能将第一个参数的结果收集到第二个参数中的函数式 * @param <SRC> * @param <COLLECT_TARGET> */// @FunctionalInterface public interface ResultCollector<SRC, COLLECT_TARGET> { void collect(SRC src, COLLECT_TARGET collectTarget); }}
4、线程执行的具体任务
package com.akk.thread;import java.util.List;import java.util.concurrent.Callable;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Component;import com.akk.mvc.entity.UserTestEntity;import com.akk.mvc.service.UserService;/** * 线程执行的具体任务 * 批量保存用户信息 */@Componentpublic class BatchListTask implements Callable<List<UserTestEntity>> {private List<UserTestEntity> batchDebitList = null;@Autowiredprivate UserService userService;public List<UserTestEntity> getBatchDebitList() {return batchDebitList;}public void setBatchDebitList(List<UserTestEntity> batchDebitList) {this.batchDebitList = batchDebitList;}public UserService getUserService() {return userService;}public void setUserService(UserService userService) {this.userService = userService;}@Overridepublic List<UserTestEntity> call() throws Exception {return userService.batchInsert(batchDebitList);}}
5、Junit入口
package com.akk.test;import java.util.ArrayList;import java.util.List;import java.util.concurrent.ExecutionException;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.TimeoutException;import org.junit.Test;import org.junit.runner.RunWith;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.test.context.ContextConfiguration;import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;import com.akk.mvc.entity.UserTestEntity;import com.akk.mvc.service.UserService;import com.akk.thread.BatchListTask;import com.akk.thread.BatchUtil;import com.akk.thread.ThreadUtil;@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration(locations = "classpath:conf/applicationContext.xml")public class ThreadTest {@Autowiredprivate UserService userService; @Autowired private ThreadUtil pool; @Testpublic void thread() {List<BatchListTask> tasks = new ArrayList<BatchListTask>();List<UserTestEntity> userTestEntityList = new ArrayList<UserTestEntity>();for (int i = 0; i < 20; i++) {UserTestEntity userTestEntity = new UserTestEntity();userTestEntity.setUserId(i);userTestEntityList.add(userTestEntity);}List<List<UserTestEntity>> updateBatchList = BatchUtil.getBatchList(userTestEntityList, 5);for (List<UserTestEntity> list : updateBatchList) {BatchListTask batchListTask = new BatchListTask();batchListTask.setBatchDebitList(list);batchListTask.setUserService(userService);tasks.add(batchListTask);}try {List<List<UserTestEntity>> result = pool.execute(tasks);for(List<UserTestEntity> thisList : result){for(UserTestEntity thisEntity : thisList){thisEntity.getId();System.out.println("id:"+thisEntity.getId());}}System.out.println(result.size());} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (ExecutionException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (TimeoutException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}
阅读全文
0 0
- java多线程:ExecutorService多线程实例(六)
- Java多线程之ExecutorService
- ExecutorService实现java多线程
- Java多线程之ExecutorService
- Java多线程之ExecutorService
- JAVA多线程计算ExecutorService
- JAVA多线程之ExecutorService
- java多线程之ExecutorService
- Java多线程系列-ExecutorService
- Java ExecutorService 多线程实践(一)
- java多线程:ExecutorService解析(五)
- java多线程[9]:线程池(ExecutorService)
- JAVA多线程之Executor&ExecutorService
- java 使用ExecutorService 建立多线程
- Java多线程--ExecutorService的使用
- ExecutorService多线程
- Java多线程工具包java.util.concurrent---ExecutorService
- java多线程学习(六)
- Python常用软件安装
- 欢迎使用CSDN-markdown编辑器
- Android切换Fragment时视频依旧在播放,没有正常的停止。
- 端午节踩楼中奖特此留恋
- 学习日记//harshtable
- java多线程:ExecutorService多线程实例(六)
- 腾讯2017暑期实习生编程题(三)----有趣的数字
- springmvc的工作流程
- AKOJ -- 1529 -- 寻找最大数
- Arduino 编程技巧 睡眠模式的运用 2个AA电池运行一年的秘密(未完待续)
- MYSQL
- Intellij Idea 使用技巧
- Win32API学习笔记第七章(三)
- Arduino Uno 无声无息的开关 固态继电器(四引脚)的实验