Java并发编程高级篇(九):在线程之行结束后再做些什么
2017-03-02 00:00
441 查看
如果我们想要在线程执行结束后做一些事情,比如生成报表,发送通知邮件或者释放一些系统资源,FutureTask类给于我们最好的支持。
想要实现这种控制方式,我们不能直接把Callable<?>对象直接提交到线程执行器中运行,而是要借助FutureTask类,把需要执行的线程类发送给FutureTask对象,然后把FutureTask类发送给执行器去执行。
首先创建线程类,实现Callable接口(不能使用Runnable)。休眠一个随机时间来模拟线程执行过程。
接下来我们继承FutureTask类实现自己的ResultTask类,并重写done方法。在done方法中即可定义任务执行完毕的处理逻辑,在这里我们打印线程的一些状态。
在主线程类中,我们创建5个线程任务,因为FutureTask实现了Runnable接口,所以可以直接提交到执行器去运行。主线程休眠5s,然后以此取消5个线程。最后打印已经执行完成的任务的信息。
控制台中你可以看到,每个线程的休眠时间,以及线程结束时的状态。还有执行完成线程的信息。
想要实现这种控制方式,我们不能直接把Callable<?>对象直接提交到线程执行器中运行,而是要借助FutureTask类,把需要执行的线程类发送给FutureTask对象,然后把FutureTask类发送给执行器去执行。
首先创建线程类,实现Callable接口(不能使用Runnable)。休眠一个随机时间来模拟线程执行过程。
import java.util.concurrent.Callable; import java.util.concurrent.TimeUnit; /** * 创建一个雷ExecutableTask实现Callable<String>接口。 * * 延迟一定是坚守执行 * * Created by hadoop on 2016/11/3. */ public class ExecutableTask implements Callable<String> { private String name; public ExecutableTask(String name) { this.name = name; } @Override public String call() throws Exception { long duration = (long)(Math.random() * 10); System.out.printf("Task: %s will delay %d \n", name, duration); TimeUnit.SECONDS.sleep(duration); return "Hello, I am " + name; } public String getName() { return name; } }
接下来我们继承FutureTask类实现自己的ResultTask类,并重写done方法。在done方法中即可定义任务执行完毕的处理逻辑,在这里我们打印线程的一些状态。
import java.util.concurrent.Callable; import java.util.concurrent.FutureTask; /** * 创建类ResultTask继承FutureTask<String>类 * * 重写done()方法:打印任务isCancelled()状态还是完成状态。 * * Created by hadoop on 2016/11/3. */ public class ResultTask extends FutureTask<String> { private String name; public ResultTask(Callable<String> callable) { super(callable); this.name = ((ExecutableTask)callable).getName(); } @Override protected void done() { if (isCancelled()) { System.out.printf("%s: Has been canceled.\n", name); } else { System.out.printf("%s: Has been finished.\n", name); } } }
在主线程类中,我们创建5个线程任务,因为FutureTask实现了Runnable接口,所以可以直接提交到执行器去运行。主线程休眠5s,然后以此取消5个线程。最后打印已经执行完成的任务的信息。
import java.util.concurrent.ExecutionException; import java.util.concurrent.Executors; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; /** * Created by hadoop on 2016/11/3. * * 在任务结束的时候FutureTask类就会调用done()方法。 * * 创建一个实现Callable接口的ExecutableTask类 * 创建一个阶乘FutureTask类的ResultTask类 * * 然后我们就可以在done方法啊中做出一些资源释放之类的工作了 * */ public class Main { public static void main(String[] args) throws InterruptedException, ExecutionException { ThreadPoolExecutor executor = (ThreadPoolExecutor)Executors.newCachedThreadPool(); ResultTask[] tasks = new ResultTask[5]; for (int i = 0; i < 5; i++) { ExecutableTask task = new ExecutableTask("Task" + String.valueOf(i)); tasks[i] = new ResultTask(task); executor.submit(tasks[i]); } TimeUnit.SECONDS.sleep(5); for (int i = 0; i < 5; i++) { tasks[i].cancel(true); } for (int i = 0; i < 5; i++) { if (!tasks[i].isCancelled()) { System.out.println(tasks[i].get()); } } executor.shutdown(); } }
控制台中你可以看到,每个线程的休眠时间,以及线程结束时的状态。还有执行完成线程的信息。
Task: Task0 will delay 3 Task: Task4 will delay 1 Task: Task3 will delay 5 Task: Task2 will delay 8 Task: Task1 will delay 0 Task1: Has been finished. Task4: Has been finished. Task0: Has been finished. Task2: Has been canceled. Task3: Has been canceled. Hello, I am Task0 Hello, I am Task1 Hello, I am Task4
相关文章推荐
- Java并发编程之线程管理(高级线程同步7)
- Java并发编程之线程管理(高级线程同步8)
- Java并发编程之线程管理(高级线程同步9)
- Java并发编程之线程管理(高级线程同步10)
- Java并发编程高级篇(二):使用固定大小线程执行器
- Java并发编程:如何创建线程?
- JAVA 并发编程随笔【七】线程安全与共享资源
- JAVA 并发编程随笔【七】线程安全与共享资源
- JAVA 并发编程随笔【七】线程安全与共享资源
- Java 并发编程:线程间的协作(wait/notify/sleep/yield/join)
- Java并发编程:进程和线程之由来__进程让操作系统的并发性成为可能,而线程让进程的内部并发成为可能
- Java并发编程基础-线程-状态
- java并发编程-再谈daemon线程
- Java并发编程:进程和线程的由来(转)
- [Java并发编程]-二、线程信息获取与设置
- UNIX环境高级编程——线程属性之并发度
- 【Java并发编程】之二:线程中断(含代码)
- 线程高级应用-心得5-java5线程并发库中Lock和Condition实现线程同步通讯
- JAVA 并发编程随笔【五】Thread线程创建及运行线程任务
- JAVA 并发编程随笔【五】Thread线程创建及运行线程任务