Fork/Join——ForkJoinPool核心方法(二)

12.
方法
public boolean isShutdown()
的使用
public class Demo3 {
    public static void main(String[] args) throws InterruptedException {
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                try {
                    System.out.println("打印了!begin " + Thread.currentThread().getName());
                    Thread.sleep(1000);
                    System.out.println("打印了!end" + Thread.currentThread().getName());
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        };

        ForkJoinPool pool = new ForkJoinPool();
        pool.execute(runnable);
        System.out.println("A=" + pool.isShutdown());
        pool.shutdown();
        Thread.sleep(5000);
        System.out.println("B=" + pool.isShutdown());
    }
}

任务成功被运行。
在这里插入图片描述

public class Demo3 {
    public static void main(String[] args) throws InterruptedException {
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                try {
                    System.out.println("打印了!begin " + Thread.currentThread().getName());
                    Thread.sleep(1000);
                    System.out.println("打印了!end" + Thread.currentThread().getName());
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        };

        ForkJoinPool pool = new ForkJoinPool();
        pool.execute(runnable);
        System.out.println("A=" + pool.isShutdown());
        pool.shutdownNow();
        Thread.sleep(5000);
        System.out.println("B=" + pool.isShutdown());
    }
}

在这里插入图片描述

任务成功被运行,由于shutdownNow()方法在源代码内部使用了interrupt() 方法,所以interrupt()方法遇到sleep()抛出“ java.lang.InterruptedException: sleep interrupted”异常。

如果使用Callable接口,则需要使用Future对象的get()方法获得异常。

13.
方法
public boolean awaitTermination(long timeout, TimeUnit unit)
的使用

方法awaitTermination(long timeout, TimeUnit unit)的作用是等待池被销毁的最长时间,具有阻塞特性。

public class Demo4 {
    public static void main(String[] args) throws InterruptedException {
        Runnable_a a = new Runnable_a();
        ForkJoinPool pool = new ForkJoinPool();
        pool.execute(a);
        System.out.println("main begin! " + System.currentTimeMillis());
        //awaitTermination具有阻塞特性
        System.out.println(pool.awaitTermination(10, TimeUnit.SECONDS));
        System.out.println("main end! " + System.currentTimeMillis());
    }
}

class Runnable_a implements  Runnable {

    @Override
    public void run() {
        try {
            System.out.println("begin " + Thread.currentThread().getName() + " " + System.currentTimeMillis());
            Thread.sleep(4000);
            System.out.println("end " + Thread.currentThread().getName() + " " + System.currentTimeMillis());
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

class Runnable_b implements  Runnable {

    @Override
    public void run() {
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

返回值打印false,说明任务池并没有被销毁。
在这里插入图片描述

在这里插入图片描述
日志main begin和main end之间的时差差4秒,返回值打印true,代表任务池在4秒后.被销毁,所以awaitTermination(long timeout, TimeUnit unit)要结合shutdown()方法进行使用。
在这里插入图片描述

14.
方法
public <T> T invoke(ForkJoinTask<T> task)
的使用
public class Demo5 {
    public static void main(String[] args) {
        RecursiveAction_ action = new RecursiveAction_();
        ForkJoinPool pool = new ForkJoinPool();
        pool.invoke(action);
    }
}


class RecursiveAction_ extends RecursiveAction {

    @Override
    protected void compute() {
        System.out.println("TheadName=" + Thread.currentThread().getName());
    }
}

class RecursiveTask_ extends RecursiveTask<String> {

    @Override
    protected String compute() {
        return "我是返回值";
    }
}

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

方法execute(task)、submit(task) 以及invoke(task) 都可以在异步队列中执行任务,需要注意的是,方法invoke()是阻塞的,而它们在使用上的区别其实很简单:

  • execute(task) 只执行任务,没有返回值
  • 而submit(task)方法有返回值,返回值类型是ForkJoinTask, 想取得返回值时,需要使用ForkJoinTask对象的get() 方法
  • 而invoke(task)和submit(task)方法一样都具有返回值的功能,区别就是invoke(task)方法直接将返回值进行返回,而不是通过ForkJoinTask对象的get(方法。

这3个方法的声明如下:

pool.execute(task);
//pulic void execute(ForkJoinTask<?> task)

pool.submit(task);
//public <T> ForkJoinTask<T> submit(ForkJoinTask<T> task)

pool.invoke(task);
//public <T> T invoke(ForkJoinTask<T> task)
15. 监视pool池的状态
  • 方法getParallelism():获得并行的数量,与CPU的内核数有关;
  • 方法getPoolSize():获得任务池的大小;
  • 方法getQueuedSubmissionCount():取得已经提交但尚未被执行的任务数量;
  • 方法hasQueuedSubmissions():判断队列中是否有未执行的任务;
  • 方法getActiveThreadCount():获得活动的线程个数;
  • 方法getQueuedTaskCount():获得任务的总个数;
  • 方法getStealCount():获得偷窃的任务个数;
  • 方法getRunningThreadCount():获得正在运行并且不在阻塞状态下的线程个数;
  • 方法isQuiescent():判断任务池是否是静止未执行任务的状态。
public class Demo6 {
    public static void main(String[] args) {
        MyRecursiveTask_1 task_1 = new MyRecursiveTask_1();
        MyRecursiveTask_1 task_2 = new MyRecursiveTask_1();
        MyRecursiveTask_1 task_3 = new MyRecursiveTask_1();
        ForkJoinPool pool = new ForkJoinPool();
        pool.submit(task_1);
        pool.submit(task_2);
        pool.submit(task_3);
        System.out.println("并行数getParallelism()=" + pool.getParallelism());
        System.out.println("线程池大小getPoolSize()=" + pool.getPoolSize());
        do {
        }while (!pool.isTerminated());
        System.out.println("main end");
    }
}

class MyRecursiveTask_1 extends RecursiveAction {

    @Override
    protected void compute() {
        try {
            System.out.println("begin=" + Thread.currentThread().getName());
            Thread.sleep(1000);
            System.out.println("end=" + Thread.currentThread().getName());
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

ForkJoinTask对异常的处理
  • 方法isCompletedAbnormally()判断任务是否出现异常
  • 方法isCompletedNormally()判断任务是否正常执行完毕
  • 方法getException()返回报错异常
public class Demo7 {
    public static void main(String[] args) throws InterruptedException {
        MyRecursiveTaskX taskX = new MyRecursiveTaskX();
        ForkJoinPool pool = new ForkJoinPool();
        ForkJoinTask<Integer> submit = pool.submit(taskX);
        System.out.println(submit.isCompletedAbnormally() + " " + submit.isCompletedNormally());
        Thread.sleep(2000);
        System.out.println(submit.isCompletedAbnormally() + " " + submit.isCompletedNormally());
        System.out.println(submit.getException());
    }
}

class MyRecursiveTaskX extends RecursiveTask<Integer> {

    @Override
    protected Integer compute() {
        try {
            Thread.sleep(1000);
            Integer.parseInt("a");
        } catch (NumberFormatException e) {
            e.printStackTrace();
            //需要抛出NumberFromatException异常,MyRecursiveTaskX对象从而可以获得任务执行的结果的情况
            throw e;
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return 100;
    }
}

在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值