您的位置:首页 > 编程语言 > Java开发

Java多线程之 Callable、Future和FutureTask

2013-09-22 17:57 477 查看
最近在研究Android AsyncTask 源码的时候,发现用到了很多JAVA SE 多线程的知识,于是回过头来查阅JDK 文档复习了一下Java多线程的相关知识,做一个笔记方便以后查找。

JDK API 中关于Callable介绍



Callable 接口类似于 Runnable,两者都是为那些其实例可能被另一个线程执行的类设计的。但是Runnable 不会返回结果,并且无法抛出经过检查的异常。 

我们可以通过 ExecutorService
的submit 方法来提交一个Runnable或者Callable任务,并且会返回一个Future对象。



Future 表示异步计算的结果,我们可以通过 Future 对象来获取计算的结果 或者是 取消正在进行的任务。



下面通过一个例子来比较Runnable和Callable的不同之处。

package com.example.test.callable;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

public class CallableTest {

/**
* @param args
*/
public static void main(String[] args) {

// testRunnable();
testCallable();

}

private static void testCallable() {

ExecutorService pool = Executors.newFixedThreadPool(3);

CalculateCallable task1 = new CalculateCallable(0);
CalculateCallable task2 = new CalculateCallable(1);
CalculateCallable task3 = new CalculateCallable(3);

try {
// 提交并执行任务,任务启动时返回了一个 Future对象,
// 如果想得到任务执行的结果或者是异常可对这个Future对象进行操作
Future<Integer> future1 = pool.submit(task1);
// 获得第一个任务的结果,如果调用get方法,当前线程会等待任务执行完毕后才往下执行
System.out.println("task1 get: " + future1.get());

Future<Integer> future2 = pool.submit(task2);
// System.out.println("task2 get: " + future2.get(2000,
// TimeUnit.MILLISECONDS));
// 等待5秒后,再停止第二个任务,因为第二个任务进行的是无限循环
Thread.sleep(8000);
System.out.println("task2 cancel: " + future2.cancel(true));

Future<Integer> future3 = pool.submit(task3);
System.out.println("task3 get: " + future3.get());

} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}

// 停止任务执行服务
pool.shutdownNow();
}

private static void testRunnable() {

CalculateRunnable task1 = new CalculateRunnable(0);
CalculateRunnable task2 = new CalculateRunnable(1);
CalculateRunnable task3 = new CalculateRunnable(3);

ExecutorService pool = Executors.newFixedThreadPool(3);

try {
Future<?> future1 = pool.submit(task1);
System.out.println("task1 get: " + future1.get());

Future<?> future2 = pool.submit(task2);
// System.out.println("task2 get: " + future2.get());

// 等待5秒后,再停止第二个任务
Thread.sleep(8000);
System.out.println("task2 cancel: " + future2.cancel(true));

Future<?> future3 = pool.submit(task3);
System.out.println("task3 get: " + future3.get());

} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}

// 停止任务执行服务
pool.shutdownNow();
}

public static class CalculateCallable implements Callable<Integer> {

private int param = -1;

public CalculateCallable(int param) {
this.param = param;
}

@Override
public Integer call() throws Exception {

if (this.param == 0) {

System.out.println("no loop********" + param);
return 0;
} else if (this.param == 1) {

// 如果flag的值为1,做一个无限循环
try {
while (true) {
System.out.println("while looping********" + param);
Thread.sleep(2000);
}
} catch (InterruptedException e) {
System.out.println("Interrupted");
}
return 1;
} else {
throw new Exception("illegal argument!"+param);
}
}
}

public static class CalculateRunnable implements Runnable {

private int param = -1;

public CalculateRunnable(int param) {
this.param = param;
}

@Override
public void run() {

if (this.param == 0) {
System.out.println("param=" + param + "***over");
} else if (this.param == 1) {

// 如果flag的值为1,做一个无限循环
try {
while (true) {
System.out.println("looping********" + param);
Thread.sleep(2000);
}
} catch (InterruptedException e) {
System.out.println("Interrupted");
}
System.out.println("param=" + param + "***over");
} else {
System.out.println("illegal argument!"+param);
}
}
}
}


FutureTask,可取消的异步计算。仅在计算完成时才能获取结果;如果计算尚未完成,则阻塞 get 方法



package com.example.test.callable;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

public class FutureTaskTest {

/**
* @param args
*/
public static void main(String[] args) {

testFutureTask();
}

private static void testFutureTask() {

Worker worker = new Worker(); // 工作线程

FutureTask<Integer> ft = new FutureTask<Integer>(worker);

new Thread(ft).start();

while (!ft.isDone()) {
try {
System.out.println("monitor worker thread...");

Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}

try {
int amount = ft.get();	//返回值
System.out.println("amount="+amount);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}

public static class Worker implements Callable<Integer> {

private int flag = 100;
private int retVal = 0;

@Override
public Integer call() throws Exception {
while (flag > 0) {
System.out.println("I'm working......"+flag);

flag--;
retVal++;
Thread.sleep(1000);
}
return retVal;
}
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Callable Future
相关文章推荐