首页 > 代码库 > 多线程08-Callable和Future

多线程08-Callable和Future

1.简介

     Callable是一个接口,与Runnable类似,包含一个必须实现的call方法,可以启动为让另一个线程来执行,执行Callable可以得到一个Future对象 该对象可以监听Callable的执行结果 也可以取消该任务的执行

 

2.案例 

   

package org.lkl.thead.foo;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 CallableAndFuture {    public static void main(String[] args) throws InterruptedException, ExecutionException {      ExecutorService threadPool =   Executors.newSingleThreadExecutor() ;      Future<String> future =  threadPool.submit(new Callable<String>() {        @Override        public String call() throws Exception {            System.out.println("call method");            Thread.sleep(100) ;            return "liaokailin";        }    }) ;      System.out.println(" future.isCancelled():"+ future.isCancelled()); ;     while(!future.isDone()){         System.out.println("---等待结果---");     }   //   future.cancel(true) ;      System.out.println(future.get() );;    }}

 

         通过threadPool.submit可以返回一个Future对象 ,通过该对象的 future.isDone 表示Callable中的任务是否执行完成  true表示完成

         future.cancle(true) 可以取消Callable中的任务(call)

         future.get() 得到的是Callable中call方法的返回值.

         注意 代码执行到future.get()的时候会等待Callable中的call方法执行 等待执行结束以后get()方法才会执行完成 ,否则一直在等待call的执行   也可以通过 future.get(timeout, unit) 

方法来设置等待几秒以后获取call的返回值 如果没有获取到结果则返回异常.

       

3. CompletionService

     通过CompletionService可以处理一组Callable任务 ,通过其take方法可以获得Future对象

       

    ExecutorService threadPool =  Executors.newFixedThreadPool(10) ;        CompletionService<Integer> service = new ExecutorCompletionService<Integer>(threadPool) ;                for(int i =1 ;i<=10;i++){            final int flag = i ;            service.submit(new Callable<Integer>() {                @Override                public Integer call() throws Exception {                    Thread.sleep(new Random().nextInt(1000)) ;                    return flag;                }            }) ;        }                for(int i =1 ;i<=10;i++){            Future<Integer> future = service.take() ;            System.out.println(future.get() );                    }

 

结果:

81532106497

 

  执行的结果是无序的 那么说明CompletionService获得Callable的结果是 看哪个Callable先执行完成则先获得其返回的结果

 

如果将上面的 ExecutorService threadPool =  Executors.newFixedThreadPool(10) ; 方法换成:

ExecutorService threadPool =  Executors.newSingleThreadExecutor() ;

 

则执行的结果是从1-10有序的 

    那是因为当前线程池中只有一个线程  要等待for循环的第一次执行完才会去执行第二次的for循环.