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

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

但是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的实现:

1
public  class  FutureTask<V>  implements  RunnableFuture<V>

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

1
2
3
public  interface  RunnableFuture<V>  extends  Runnable, Future<V> {
     void  run();
}

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

  FutureTask提供了2个构造器:

1
2
3
4
public  FutureTask(Callable<V> callable) {
}
public  FutureTask(Runnable runnable, V result) {
}

继续看  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()方法:

1
2
3
public  interface  Runnable {
     public  abstract  void  run();
}

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

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

1
2
3
4
5
6
7
8
9
public  interface  Callable<V> {
     /**
      * Computes a result, or throws an exception if unable to do so.
      *
      * @return computed result
      * @throws Exception if unable to compute a result
      */
     V call()  throws  Exception;
}

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

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

1
2
3
<T> Future<T> submit(Callable<T> task);
<T> Future<T> submit(Runnable task, T result);
Future<?> submit(Runnable task);

  第一个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;
        }
    }
}



 


你可能感兴趣的:(Java并发编程 ExecutorService Future FutureTask Callbale的使用)