如题 (总结要点)

  • 使用ThreadPoolExecutor来创建线程,使用Callable + Future 来执行并探知线程执行情况;
  • V get (long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException 同上面的get功能一样,多了设置超时时间。参数timeout指定超时时间,uint指定时间的单位,在枚举类TimeUnit中有相关的定义。如果计算超时,将抛出TimeoutException。
  • 可以转换为FutureTask: FutureTask task = (FutureTask) poolExecutor.submit(new MyRunner(500));
  • 毕竟:class FutureTask implements RunnableFuture,interface RunnableFuture extends Runnable, Future;
  • FutureTask可以作为线程扔到线程池中运行,并且还可以像下面的Future一样探知线程的执行情况。
  • 下面的线程池poolExecutor.submit 返回的是interface RunnableFuture extends Runnable, Future (查看源码可知):
    public <T> Future<T> submit(Runnable task, T result) {
if (task == null) throw new NullPointerException();
RunnableFuture<T> ftask = newTaskFor(task, result);
execute(ftask);
return ftask;
}

借鉴学习文章列表

1.主题

Future接口提供方法来检测任务是否被执行完,等待任务执行完获得结果,也可以设置任务执行的超时时间。这个设置超时的方法就是实现Java程序执行超时的关键。

Future接口是一个泛型接口,严格的格式应该是Future<V>,其中V代表了Future执行的任务返回值的类型。 Future接口的方法介绍如下:

boolean cancel (boolean mayInterruptIfRunning) 取消任务的执行。参数指定是否立即中断任务执行,或者等等任务结束
boolean isCancelled () 任务是否已经取消,任务正常完成前将其取消,则返回 true
boolean isDone () 任务是否已经完成。需要注意的是如果任务正常终止、异常或取消,都将返回true
V get () throws InterruptedException, ExecutionException 等待任务执行结束,然后获得V类型的结果。InterruptedException 线程被中断异常, ExecutionException任务执行异常,如果任务被取消,还会抛出CancellationException
V get (long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException 同上面的get功能一样,多了设置超时时间。参数timeout指定超时时间,uint指定时间的单位,在枚举类TimeUnit中有相关的定义。如果计算超时,将抛出TimeoutException
Future的实现类有java.util.concurrent.FutureTask<V>即 javax.swing.SwingWorker<T,V>。通常使用FutureTask来处理我们的任务。FutureTask类同时又实现了Runnable接口,所以可以直接提交给Executor执行。

2. 代码

/**
* 测试子线程,计算100以内的整数和
*/ class MyRunner implements Callable<Integer>{
private int sleepTime ; public MyRunner(int sleepTime) {
this.sleepTime = sleepTime;
} Logger logger = Logger.getLogger("myRunner");
@Override
public Integer call() throws Exception {
logger.info("子线程开始运行");
Thread.sleep(sleepTime);
int sum = 0;
for(int i=1;i<=100;i++){
sum += i;
}
logger.info(sleepTime/1000.0+"s后,子线程结束运行.100以内的正数和为:"+sum);
return sum;
}
}

3.测试 主线程启动

import java.util.concurrent.*;
import java.util.logging.Logger; /** https://www.cnblogs.com/dolphin0520/p/3949310.html
* 《java并发编程的艺术》
*/
public class Test {
private static Logger logger = Logger.getLogger("Test");
public static void main(String[] args) {
/**
* 测试Callable 接口
* 这是一个泛型接口,call()函数返回的类型就是传递进来的V类型
* Callable一般是和ThreadPoolExecutor配合来使用的
* 使用futureTask
*/
BlockingQueue<Runnable> queue = new SynchronousQueue<>();
ThreadFactory nameThreadFactory = new ThreadFactory() {
@Override
public Thread newThread(Runnable r) {
return new Thread(r);
}
};
ThreadPoolExecutor poolExecutor =
new ThreadPoolExecutor(2, 2, 0, TimeUnit.MILLISECONDS, queue, nameThreadFactory); /**
* 将实现Callable 或者runnable 接口的类提交给线程池即可
* */
Future<Integer> task = poolExecutor.submit(new MyRunner(500)); poolExecutor.shutdown(); try {
task.get(100,TimeUnit.MILLISECONDS);
logger.info("打印submit执行结果?是否done?");
boolean done = task.isDone();
logger.info(String.valueOf(done));
// 如果没有完成,取消当前线程的运行
if(!done){
task.cancel(true);
}
} catch (InterruptedException e) {
task.cancel(true);
} catch (ExecutionException e) {
task.cancel(true);
} catch (TimeoutException e) {
logger.info("超时");
task.cancel(true);
} logger.info("所有任务执行完毕");
}
}

测试结果

八月 16, 2019 10:05:18 上午 com.thread.MyRunner call
信息: 子线程开始运行
八月 16, 2019 10:05:18 上午 com.thread.Test main
信息: 超时
八月 16, 2019 10:05:18 上午 com.thread.Test main
信息: 所有任务执行完毕

测试结果2 修改 探知时间 task.get(1000,TimeUnit.MILLISECONDS);

八月 16, 2019 10:25:20 上午 com.thread.MyRunner call
信息: 子线程开始运行
八月 16, 2019 10:25:20 上午 com.thread.MyRunner call
信息: 0.5s后,子线程结束运行.100以内的正数和为:5050
八月 16, 2019 10:25:20 上午 com.thread.Test main
信息: 打印submit执行结果?是否done?
八月 16, 2019 10:25:20 上午 com.thread.Test main
信息: true
八月 16, 2019 10:25:20 上午 com.thread.Test main
信息: 所有任务执行完毕

Java并发编程:ThreadPoolExecutor + Callable + Future(FutureTask) 探知线程的执行状况的更多相关文章

  1. Java并发编程:Callable、Future和FutureTask

    作者:海子 出处:http://www.cnblogs.com/dolphin0520/ 本博客中未标明转载的文章归作者海子和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置 ...

  2. (转)Java并发编程:Callable、Future和FutureTask

    Java并发编程:Callable.Future和FutureTask 在前面的文章中我们讲述了创建线程的2种方式,一种是直接继承Thread,另外一种就是实现Runnable接口. 这2种方式都有一 ...

  3. Java并发编程:Callable、Future和FutureTask(转)

    Java并发编程:Callable.Future和FutureTask 在前面的文章中我们讲述了创建线程的2种方式,一种是直接继承Thread,另外一种就是实现Runnable接口. 这2种方式都有一 ...

  4. 15、Java并发编程:Callable、Future和FutureTask

    Java并发编程:Callable.Future和FutureTask 在前面的文章中我们讲述了创建线程的2种方式,一种是直接继承Thread,另外一种就是实现Runnable接口. 这2种方式都有一 ...

  5. 007 Java并发编程:Callable、Future和FutureTask

    原文https://www.cnblogs.com/dolphin0520/p/3949310.html Java并发编程:Callable.Future和FutureTask 在前面的文章中我们讲述 ...

  6. Java并发编程 - Runnbale、Future、Callable 你不知道的那点事(二)

    Java并发编程 - Runnbale.Future.Callable 你不知道的那点事(一)大致说明了一下 Runnable.Future.Callable 接口之间的关系,也说明了一些内部常用的方 ...

  7. Java并发编程 - Runnbale、Future、Callable 你不知道的那点事(一)

    从事Java开发已经快两年了,都说Java并发编程比较难,比较重要,关键面试必问,但是在我的日常开发过程中,还真的没有过多的用到过并发编程:这不疫情嘛,周末不能瞎逛,就看看师傅们常说的 Runnabl ...

  8. java并发编程--Runnable Callable及Future

    1.Runnable Runnable是个接口,使用很简单: 1. 实现该接口并重写run方法 2. 利用该类的对象创建线程 3. 线程启动时就会自动调用该对象的run方法 通常在开发中结合Execu ...

  9. Java 并发编程:Callable和Future

    项目中经常有些任务需要异步(提交到线程池中)去执行,而主线程往往需要知道异步执行产生的结果,这时我们要怎么做呢?用runnable是无法实现的,我们需要用callable实现. import java ...

随机推荐

  1. C# ini配置文件操作类

    /// <summary> /// INI文件操作类 /// </summary> public class IniFileHelper { /// <summary&g ...

  2. 微慕WordPress小程序增强版

    2017年1月9日,张小龙在2017微信公开课Pro上发布的微信小程序正式上线.在过去的2年多的时间里,微信小程序领头,各大互联网平台也不甘落后,陆续推出自己的小程序.2018年7月4日,百度智能小程 ...

  3. spark 资源动态分配

    'spark.shuffle.service.enabled': 'true', 'spark.dynamicAllocation.enabled': 'false', , , , 'spark.sq ...

  4. 关于Class: ES6 JavaScript的class的静态方法、属性和实例属性。

    1.什么叫做静态方法? 1.1.类相当于实例的原型, 所有在类中定义的方法, 都会被实例继承.如果在一个方法前,加上Static关键字,就表示该方法不会被继承,而是直接通过类来调用,这被称为 “静态方 ...

  5. Python 绘制 柱状图

    用Python 绘制 柱状图,使用的是bar()函数. 一个简单的例子: # 创建一个点数为 8 x 6 的窗口, 并设置分辨率为 80像素/每英寸 plt.figure(figsize=(10, 1 ...

  6. Tp中使用Xunsearch

    可以将安装目录下的核心代码拷贝到Vendor中. 命名为xunsearch. 然后引入使用. vendor('xunsearch.lib.XS'); $xs = new \XS('demo'); // ...

  7. [转帖]Kubernetes v1.17 版本解读 | 云原生生态周报 Vol. 31

    Kubernetes v1.17 版本解读 | 云原生生态周报 Vol. 31 https://www.kubernetes.org.cn/6252.html 2019-12-13 11:59 ali ...

  8. golang gin框架设置静态目录

    router := gin.Default() 第一个参数是api 第二个静态问价的文件夹相对目录 router.StaticFS("/data", http.Dir(" ...

  9. git在使用push指令的时候产生的错误

    一.问题我们在使用git指令的时候往往会出现如下错误. $ git push -u origin master To https://github.com/pzq7025/ss-fly.git ! [ ...

  10. C#文件操作之把一个文件复制到另外一个文件夹下

    一.文件复制例子如下,具体情况,根据需求扩展. /// <summary> /// /// </summary> /// <param name="srcFol ...