zoukankan      html  css  js  c++  java
  • 多线程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() );
                
            }

    结果:

    8
    1
    5
    3
    2
    10
    6
    4
    9
    7

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

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

    ExecutorService threadPool =  Executors.newSingleThreadExecutor() ;

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

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

  • 相关阅读:
    2-分类
    1-确定变量间是否有关系—显著性检验
    git简单操作
    Hadoop HA和Hbase HA
    Docker入门操作
    内存数据库专题(MemCached 和Redis)
    Spark MLlib和Sprk GraphX
    Spark 调优
    Spark Streaming基础
    Spark SQL
  • 原文地址:https://www.cnblogs.com/liaokailin/p/3794349.html
Copyright © 2011-2022 走看看