如题 (总结要点)

  • 使用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并发编程--Runnable Callable及Future

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

  7. Java 并发编程:Callable和Future

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

  8. Java并发编程原理与实战五:创建线程的多种方式

    一.继承Thread类 public class Demo1 extends Thread { public Demo1(String name) { super(name); } @Override ...

  9. [Java 并发] Java并发编程实践 思维导图 - 第二章 线程安全性

    依据<Java并发编程实践>一书整理的思维导图.

随机推荐

  1. Mysql相关集锦

    1.MyBatis中设置或获取插入的自增主键 http://my.oschina.net/kolbe/blog/512904 2.MySql性能调优与架构设计系列 http://www.cnblogs ...

  2. Selenium

    Selenium可以抓取完整的页面的html但是request 和java的url不能抓的很完整. selenium的方法是dirver.page_source

  3. Linux操作系统下的Sudo命令

    查看.修改或者执行某些命令需要root用户的权限,如果不想直接切换到root用户,就可以使用sudo命令.sudo命令用于针对单个命令授予临时权限.sudo仅在需要时授予用户权限,减少了用户因为错误执 ...

  4. Ubuntu 12.04 SSH 安装

    By default Ubuntu Desktop OS comes with ssh clientpackage. It does not include ssh server package wh ...

  5. (转)FastDFS_v5.05安装配置

    http://my.oschina.net/shking/blog/165326 http://blog.csdn.net/yecong111/article/details/42646523 htt ...

  6. Oracle查看被锁的表和解锁[转]

    查看被锁的表 select p.spid,a.serial#, c.object_name,b.session_id,b.oracle_username,b.os_user_name from v$p ...

  7. 棒槌的工作第11天-----------------------单词(select和epoll)

    https://baike.baidu.com/item/epoll/10738144?fr=aladdin epoll百科 https://baike.baidu.com/item/select%2 ...

  8. 【Django】django.core.exceptions.ImproperlyConfigured: Error loading MySQLdb module.

    最近学习Django的过程中,在cmd打算使用python manage.py shell来测试数据的时候,当我一导入自己写的model类,就发现报了这个错误django.core.exception ...

  9. Android Studio 编译: Program type already present: XXX 解决方案

    3情况1:个例 build.gradle 中 dependencies { classpath 'com.android.tools.build:gradle:3.1.1' // } 改成 depen ...

  10. WEB入门.八 背景特效

    学习内容 background属性 CSS Sprite 技术 滑动门技术 能力目标 使用background设置网页背景 使用Sprites制作平滑投票特效 使用滑动门技术实现Tab菜单 本章简介 ...