ForkJoin框架
将大任务分割为若干小任务,再将小任务得到的结果进行汇总,得到大任务结果的框架
如何使用ForkJoinPool
ForkJoinPool是一个采用ForkJoin框架的线程池,继承自AbstractExecutorService
package org.example;
import java.time.LocalTime;
import java.util.concurrent.*;
public class Main {
public static void main(String[] args) throws InterruptedException, ExecutionException {
//创建任务
Task task = new Task(1, 100);
//创建ForkJoin线程池
ForkJoinPool threadPool = new ForkJoinPool();
//提交任务
ForkJoinTask<Integer> submit = threadPool.submit(task);
//获取结果
Integer integer = submit.get();
System.out.println(integer);
//关闭线程池
threadPool.shutdown();
}
}
class Task extends RecursiveTask<Integer> {
/**
* 起始值
*/
private int start;
/**
* 结束值
*/
private int end;
public Task(int start, int end) {
this.start = start;
this.end = end;
}
/**
* 临界值
*/
private int temp = 10;
@Override
protected Integer compute() {
//判断是否可以继续分割
if ((end - start) <= temp) {
//记录计算结果
int sum = 0;
//累计开头-结尾的值
for (int i = start; i <= end; i++) {
sum += i;
}
//返回计算结果
return sum;
} else {
//取中间值
int middle = (start + end) / 2;
//计算开头-中间
Task task1 = new Task(start, middle);
//向线程池中添加此任务
task1.fork();
//计算中间-结尾
Task task2 = new Task(middle + 1, end);
task2.fork();
//合并结果
return task1.join() + task2.join();
}
}
}
监控线程池
方法 描述 getActiveCount() 获取正在工作的线程数 getPoolSize() 获取当前存在的线程数 getLargestPoolSize() 获取历史最大的线程数 getTaskCount() 获取已提交的任务数 getCompletedTaskCount() 获取已完成的任务数 getQueue() 获取任务队列
具体代码
MonitorThreadPool
创建一个MonitorThreadPool类实现ThreadPoolExecutor接口
package org.example;
import java.util.concurrent.*;
public class MonitorThreadPool extends ThreadPoolExecutor {
public MonitorThreadPool(int corePoolSize, int maximumPoolSize,
long keepAliveTime, TimeUnit unit,
BlockingQueue<Runnable> workQueue) {
super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
}
@Override
protected void beforeExecute(Thread t, Runnable r) {
//每次任务执行前调用
monitor();
}
@Override
protected void afterExecute(Runnable r, Throwable t) {
//每次任务完成后调用
monitor();
}
@Override
public boolean isTerminated() {
//在线程池关闭前调用
monitor();
return false;
}
/**
* 监控线程池情况
*/
public void monitor() {
System.out.print("正在工作线程数" + getActiveCount() + "\t");
System.out.print("当前存在的线程数" + getPoolSize() + "\t");
System.out.print("历史最大的线程数" + getLargestPoolSize() + "\t");
System.out.print("已提交的任务数" + getTaskCount() + "\t");
System.out.print("已完成的任务数" + getCompletedTaskCount() + "\t");
System.out.println("任务队列中的任务数" + getQueue());
}
}
Main
package org.example;
import java.time.LocalTime;
import java.util.concurrent.*;
public class Main {
public static void main(String[] args) {
//创建带监控的线程池
MonitorThreadPool threadPool = new MonitorThreadPool(1, 3, 0, TimeUnit.SECONDS, new LinkedBlockingDeque<>(2));
try {
//提交多个任务
for (int i = 5; i > 0; i--) {
//创建任务
Task task = new Task(i);
//提交任务
threadPool.submit(task);
//每隔500毫秒提交一个任务
Thread.sleep(500);
}
//使主线程休眠6秒钟
Thread.sleep(6000);
//关闭线程池之前获取一次情况
threadPool.monitor();
} catch (InterruptedException e) {
throw new RuntimeException(e);
} finally {
threadPool.shutdown();
}
}
}
class Task implements Runnable {
/**
* 执行时间
*/
private int timeout;
public Task(int timeout) {
this.timeout = timeout;
}
@Override
public void run() {
try {
Thread.sleep(timeout * 1000L);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}