分享

Java多线程执行--加速任务速度

 孟船长 2022-08-28 发布于内蒙古

最近工作有一个任务,因为要上传测试报告到Aritifactory3000+测试文件使用单线程上传需要半个小时多。效率太低,于是考虑使用多线程实现。在网上找到了一个完美的解决方案:

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

如果您觉得对您有帮助,请帮忙点一下公众号文中和最底部的广告,点一下就可以,谢谢~

    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多