如题,多线程处理一个比较耗时的任务,比如耗时为 100 * 100ms 的大的文本解析任务,可以使用多线程处理,并实时反馈任务进度;
代码没有经过生产验证,只是自己想法的实现,关于线程池的知识,可以参考 传送门;
package concurrent;
import java.util.concurrent.*;
/**
* 多线程处理大任务的进度百分比
*/
public class ProcessRate {
private static ExecutorService executorService;
int process;
Object obj_lock = new Object();
// 用于在主线程计时总任务的耗时
CountDownLatch countDownLatch = null;
class ProcessWork implements Runnable {
int count;
ProcessWork(int count) {
this.count = count;
}
@Override
public void run() {
while (count > 0) {
count--;
try {
Thread.sleep(100);
showProcessRate();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
countDownLatch.countDown();
}
}
public static void main(String[] args) throws InterruptedException {
ProcessRate processRate = new ProcessRate();
int allSize = 100;
int threadNum = 10;
processRate.countDownLatch = new CountDownLatch(threadNum);
processRate.startOneThreadDealAll(allSize, threadNum);
executorService.shutdownNow();
}
private void showProcessRate() {
synchronized (obj_lock) {
process++;
System.out.println("任务进度: " + process + "%");
}
}
/**
* 启动指定的线程数,处理指定大小的任务
*
* @param allSize 任务大小
* @param threadNum 线程个数
* @throws InterruptedException
*/
private void startOneThreadDealAll(int allSize, int threadNum) throws InterruptedException {
int num = threadNum;
int threadSize = allSize / threadNum;
int lastThreadSize = allSize % threadNum == 0 ? threadSize : (allSize - threadSize * (threadNum - 1));
long start = System.currentTimeMillis();
while (threadNum > 0) {
ProcessWork processWork;
if (threadNum == 1) {
processWork = new ProcessWork(lastThreadSize);
} else {
processWork = new ProcessWork(threadSize);
}
threadNum--;
executorService.execute(processWork);
}
countDownLatch.await();
System.out.println(num + " 个线程完成 " + 100 + " 大小的任务耗时 :" + (double) (System.currentTimeMillis() - start) / 1000);
}
static {
RejectedExecutionHandler handler = new ThreadPoolExecutor.AbortPolicy();
BlockingQueue<Runnable> queue = new ArrayBlockingQueue<>(10);
executorService = new ThreadPoolExecutor(10, 20, 100, TimeUnit.SECONDS, queue, handler);
}
}