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

Java并发编程 ExecutorService Future FutureTask Callbale的使用

2016-04-25 14:42 651 查看
在一般的使用线程的过程中 我们都知道是不可以返回线程的执行结果的 如果想要获取线程的执行结果 就需要线程间通信或者设置某些标志位来判断是否执行完来获取

但是jdk1.5 提供了ExecutorService Future FutureTask Callbale 这几个类 可以让我们实现简单的返回执行结果的线程 下面我们来看看各个类的作用和组成

首先是 Future类:
public interface Future<V> {

boolean cancel(boolean mayInterruptIfRunning);

boolean isCancelled();

boolean isDone();

V get() throws InterruptedException, ExecutionException;

V get(long timeout, TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutException;
}
这个类 主要是提供对具体Callable 和Runnable 的执行过程的检查 是否取消 是否结束 获取执行结果 get方法 是用来获取线程执行结果的 这个方法 会 阻塞 直到任务结束 还有一个重载的get方法 这个方法会规定一个时间 如果这个时间内 任务没有执行完成那么 返回null

Future类只是一个接口 他有一个唯一实现类FutrueTask:

我们先来看一下FutureTask的实现:

 我们先来看一下FutureTask的实现:

  FutureTask类实现了RunnableFuture接口,我们看一下RunnableFuture接口的实现:

  可以看出RunnableFuture继承了Runnable接口和Future接口,而FutureTask实现了RunnableFuture接口。所以它既可以作为Runnable被线程执行,又可以作为Future得到Callable的返回值。

  FutureTask提供了2个构造器:

继续看 ExecutorService类:

这个类有submit方法 可以提交任务在未来的某个时间执行(不是立即执行的) 下面是他的方法:

public interface ExecutorService extends Executor {

void shutdown();
List<Runnable> shutdownNow();
boolean isShutdown();
boolean isTerminated();
boolean awaitTermination(long timeout, TimeUnit unit)
throws InterruptedException;
<T> Future<T> submit(Callable<T> task);
<T> Future<T> submit(Runnable task, T result);
Future<?> submit(Runnable task);
<T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)
throws InterruptedException;
<T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks,
long timeout, TimeUnit unit)
throws InterruptedException;

<T> T invokeAny(Collection<? extends Callable<T>> tasks)
throws InterruptedException, ExecutionException;
<T> T invokeAny(Collection<? extends Callable<T>> tasks,
long timeout, TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutException;
}
而 Callable 接口和Runnable接口类似 只不过它带有一个泛型V

以下Callable和Runnable内容取自
http://www.cnblogs.com/dolphin0520/p/3949310.html
先说一下java.lang.Runnable吧,它是一个接口,在它里面只声明了一个run()方法:

  由于run()方法返回值为void类型,所以在执行完任务之后无法返回任何结果。

  Callable位于java.util.concurrent包下,它也是一个接口,在它里面也只声明了一个方法,只不过这个方法叫做call():

  可以看到,这是一个泛型接口,call()函数返回的类型就是传递进来的V类型。

  那么怎么使用Callable呢?一般情况下是配合ExecutorService来使用的,在ExecutorService接口中声明了若干个submit方法的重载版本:

  第一个submit方法里面的参数类型就是Callable。

  暂时只需要知道Callable一般是和ExecutorService配合来使用的,具体的使用方法讲在后面讲述。

  一般情况下我们使用第一个submit方法和第三个submit方法,第二个submit方法很少使用。
下面写一个例子:

public class MyClass {
public static void main(String[] args) throws ExecutionException, InterruptedException {
ExecutorService executorService = Executors.newCachedThreadPool();  //运用线程池技术  当然也可以直接使用线程
MyTask task = new MyTask();   //创建一个任务对象
 //第一种方式  直接使用 Future
<span style="white-space:pre">	</span>Future<Integer> future = executorService.submit(task);  //提交任务  
//第二种方式  使用 FutureTask
// FutureTask<Integer> future= new FutureTask<Integer>(task);
    // executorService.submit(futureTask);
//第三种方式  直接使用Thread  不使用线程池  
// <span style="font-family: Verdana, Arial, Helvetica, sans-serif;">FutureTask<Integer> future= new FutureTask<Integer>(task);</span>
//Thread thread = new Thread(futureTask);
     //thread.start();
int a = future.get();
System.out.println("----"+a);
}
static class  MyTask implements Callable<Integer>{

@Override
public Integer call() throws Exception {
//此方法内含耗时任务
Thread.sleep(3000);
int count = 0;
for(int i = 0;i<100;i++){
count+=i;
}
return count;
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: