在JDK1.5之前面的创建线程的有2种方式,一种是直接继承Thread,另外一种就是实现Runnable接口。
这2种方式都有一个缺陷就是:在执行完任务之后无法获取执行结果。
如果需要获取执行结果,就必须通过共享变量或者使用线程通信的方式来达到效果,这样使用起来就比较麻烦。
这2种方式都有一个缺陷就是:在执行完任务之后无法获取执行结果。
如果需要获取执行结果,就必须通过共享变量或者使用线程通信的方式来达到效果,这样使用起来就比较麻烦。
1、而自从Java 1.5开始,就提供了Callable和Future,通过它们可以在任务执行完毕之后得到任务执行结果。
2、通过Executors.newFixedThreadPool更方便地创建线程池
3、ExecutorService提供了管理终止的方法,以及可为跟踪一个或多个异步任务执行状况而生成 Future 的方法。可以关闭 ExecutorService,这将导致其拒绝新任务。提供两个方法来关闭 ExecutorService。shutdown()方法在终止前允许执行以前提交的任务,而 shutdownNow() 方法阻止等待任务的启动并试图停止当前正在执行的任务。在终止后,执行程序没有任务在执行,也没有任务在等待执行,并且无法提交新任务。应该关闭未使用的 ExecutorService以允许回收其资源。
import java.util.Date;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class CallableAndFuture {
/**
* 自定义一个任务类,实现Callable接口
*/
public static class MyCallableClass implements Callable<String> {
// 标志位
private int flag = 0;
public MyCallableClass(int flag) {
this.flag = flag;
}
public String call() throws Exception {
if (this.flag == 0) {
// 如果flag的值为0,则立即返回
return "flag = 0";
}
if (this.flag == 1) {
// 如果flag的值为1,做一个无限循环
try {
int i = 0;
while (true) {
System.out.println("looping." + ++i);
Thread.sleep(1000);
}
} catch (InterruptedException e) {
System.out.println("Interrupted");
}
return "finished " + flag;
}
if (this.flag == 2) {
// 如果flag的值为1,做一个无限循环
try {
int i = 0;
while (true) {
System.out.println("Now 2. " + new Date());
Thread.sleep(3000);
if (++i == 6) {
return "finished " + flag;
}
}
} catch (InterruptedException e) {
System.out.println("Interrupted");
}
}
if (this.flag == 3) {
// 如果flag的值为1,做一个无限循环
try {
int i = 0;
while (true) {
System.out.println("Now 3. " + new Date());
Thread.sleep(2000);
if (++i == 6) {
return "finished " + flag;
}
}
} catch (InterruptedException e) {
System.out.println("Interrupted");
}
}
return "false";
}
}
public static void main(String[] args) {
// 定义3个Callable类型的任务
MyCallableClass task1 = new MyCallableClass(0);
MyCallableClass task2 = new MyCallableClass(1);
MyCallableClass task3 = new MyCallableClass(2);
MyCallableClass task4 = new MyCallableClass(3);
// 创建一个执行任务的服务
ExecutorService es = Executors.newFixedThreadPool(5);
try {
// 提交并执行任务,任务启动时返回了一个 Future对象,
// 如果想得到任务执行的结果或者是异常可对这个Future对象进行操作
Future<String> future1 = es.submit(task1);
// 获得第一个任务的结果,如果调用get方法,当前线程会等待任务执行完毕后才往下执行
System.out.println("task1: " + future1.get());
Future<String> future2 = es.submit(task2);
// 等待5秒后,再停止第二个任务。
Thread.sleep(5000);
System.out.println("task2 cancel: " + future2.cancel(true));
// 线程3、4交替运行
Future<String> future3 = es.submit(task3);
Future<String> future4 = es.submit(task4);
System.out.println("task3: " + future3.get());
System.out.println("task4: " + future4.get());
} catch (Exception e) {
System.out.println(e.toString());
}
// 停止任务执行服务
es.shutdownNow();
}
}