最近工作有一个任务,因为要上传测试报告到Aritifactory 3000+测试文件使用单线程上传需要半个小时多。效率太低,于是考虑使用多线程实现。在网上找到了一个完美的解决方案: package com.demo.testng;
import java.util.ArrayList; import java.util.List; import java.util.concurrent.*;
public class ThreadPoolTest { public void multiThread(int num) { long start = System.currentTimeMillis(); System.out.println("start ...."); //声明线程池 // ExecutorService executor = Executors.newFixedThreadPool(8);
//针对IO密集型的任务 int nThreads = Runtime.getRuntime().availableProcessors() * 2; System.out.println("nThreads: "+nThreads); ThreadPoolExecutor executor = new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>()); //该拒绝策略,首先判断线程池是否关闭,如果未关闭,则直接执行该线程 executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
List<Future<Integer>> futures = new ArrayList<>(); //批量提交任务 for (int i = 0; i < num; i++) { int finalI = i; futures.add( executor.submit( //线程任务 new Callable<Integer>() { @Override public Integer call() throws Exception { task(finalI); return finalI; } } )); } //获取执行完的结果 for (Future<Integer> future : futures) { try { System.out.println(String.valueOf(future.get())); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } } System.out.println("end cost: " + System.currentTimeMillis()); //关闭线程池 executor.shutdown(); }
//要执行的任务,耗时200ms private void task(int num) { try { System.out.println(" task:{" +num+ "} ,currentThread: {} "+ Thread.currentThread().getName()); Thread.sleep(200L); } catch (InterruptedException e) { e.printStackTrace(); } }
//单线程执行 public void singleThread(int num) { long start = System.currentTimeMillis(); System.out.println("start ...."); for (int i = 0; i < num; i++) { task(i); } System.out.println("end cost "+ System.currentTimeMillis() +" - start"); }
public static void main(String[] args) { ThreadPoolTest concurrentTest = new ThreadPoolTest(); //单线程耗时2秒 // concurrentTest.singleThread(10); //多线程耗时200毫秒 concurrentTest.multiThread(10); } }
使用说明singleThread 是一个单线程例子,是作者对比执行时间用的。可以删掉不看- 默认8个线程,因为
int nThreads = Runtime.getRuntime().availableProcessors() * 2; 这里乘了2 - 如果你要改成自己的任务多线程执行加速,只需要替换
call() 函数里面的代码。
public Integer call() throws Exception { task(finalI); return finalI; }
但是正常情况下你不能简单的把task() 函数替换成自己的(视情况而定),因为如果只是简单的替换就是多线程执行你的task()函数,结果是仍然是单线程执行,所以你需要把你的task()代码和这个multiThread 代码合并。把真正执行的任务的代码加到call() 方法中。这样才能真正的实现多线程。 “原文链接(原文也是只有代码)
https://www.cnblogs.com/perry666/p/15439318.html ” 如果您觉得对您有帮助,请帮忙点一下公众号文中和最底部的广告,点一下就可以,谢谢~
|