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

本文深入探讨了ForkJoinPool的多个核心方法,包括isShutdown(), awaitTermination(), invoke(), getParallelism()等,展示了如何使用这些方法来管理和监控线程池的状态。同时,文章还解析了异常处理的方法,如isCompletedAbnormally()和getException(),帮助开发者更好地理解和应用ForkJoinPool。
1627

被折叠的 条评论
为什么被折叠?



