ForkJoin框架以及监控线程池

本文介绍了Java的ForkJoin框架,如何使用ForkJoinPool将大任务分解为小任务并行执行,同时展示了如何监控线程池状态。作者通过示例展示了如何创建任务、提交任务以及线程池的管理方法。
摘要由CSDN通过智能技术生成

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);
        }
    }
}

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值