• Callable、Future、FutureTask浅析


    1、Callable<V>接口

    Runnable接口

    public interface Runnable {  
        public abstract void run();  
    } 

    Callable

    public interface Callable<V> {   
          V   call()   throws Exception;   
    }   

    runnable接口 Callable接口 都可以被ThreadPoolExecutor或ScheduledThreadPoolExecutor执行,两者实现了ExcutorService接口

    ExecutorService接口

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

    2、Future<V> 

    获得异步计算结果,说白了就是对具体的Runnable或者Callable对象任务执行的结果进行获取(get()),取消(cancel()),判断是否完成等操作。

    public interface Future<V> {  
      //如果任务没开始,cancle()将会返回true
      //如果任务已经启动,执行cancle(true)将以中断执行此任务线程的方式来试图阻止任务,成功返沪true
    //如果任务已经启动,执行cancle(false)将不会对执行线程产生影响,此时返回false
    boolean cancel(boolean mayInterruptIfRunning);
      //如果任务完成前被取消,返回true
    boolean isCancelled();
      //如果任务结束,无论是正常结束或是中途取消还是发生异常,都会true
    boolean isDone();
      //获取异步执行结果,如果没有结果可用,此方法会阻塞直到异步计算完成。 V get()
    throws InterruptedException, ExecutionException;
      //获取异步执行结果,如果没有结果可用,此方法会阻塞,
    //但是会有时间限制,如果阻塞时间超过设定的timeout时间,该方法将抛出异常。 V get(
    long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException; }

    3、FutureTask类

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

    其中

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

    构造方法:

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

    使用场景:

    1、使用Callable+Future获取执行结果

    package com.zejian.Executor;  
    import java.util.concurrent.Callable;  
    /** 
     * @author zejian 
     * @time 2016年3月15日 下午2:02:42 
     * @decrition Callable接口实例 
     */  
    public class CallableDemo implements Callable<Integer> {  
          
        private int sum;  
        @Override  
        public Integer call() throws Exception {  
            System.out.println("Callable子线程开始计算啦!");  
            Thread.sleep(2000);  
              
            for(int i=0 ;i<5000;i++){  
                sum=sum+i;  
            }  
            System.out.println("Callable子线程计算结束!");  
            return sum;  
        }  
    }  
    package com.zejian.Executor;  
    import java.util.concurrent.ExecutorService;  
    import java.util.concurrent.Executors;  
    import java.util.concurrent.Future;  
    /** 
     * @author zejian 
     * @time 2016年3月15日 下午2:05:43 
     * @decrition callable执行测试类 
     */  
    public class CallableTest {  
          
        public static void main(String[] args) {  
            //创建线程池  
            ExecutorService es = Executors.newSingleThreadExecutor();  
            //创建Callable对象任务  
            CallableDemo calTask=new CallableDemo();  
            //提交任务并获取执行结果  
            Future<Integer> future =es.submit(calTask);  
            //关闭线程池  
            es.shutdown();  
            try {  
                Thread.sleep(2000);  
            System.out.println("主线程在执行其他任务");  
              
            if(future.get()!=null){  
                //输出获取到的结果  
                System.out.println("future.get()-->"+future.get());  
            }else{  
                //输出获取到的结果  
                System.out.println("future.get()未获取到结果");  
            }  
              
            } catch (Exception e) {  
                e.printStackTrace();  
            }  
            System.out.println("主线程在执行完成");  
        }  
    } 

    执行结果:

    Callable子线程开始计算啦!
    主线程在执行其他任务
    Callable子线程计算结束!
    future.get()-->12497500
    主线程在在执行完成

    2、使用Callable+FutureTask获取执行结果

    package com.zejian.Executor;  
    import java.util.concurrent.ExecutorService;  
    import java.util.concurrent.Executors;  
    import java.util.concurrent.Future;  
    import java.util.concurrent.FutureTask;  
    /** 
     * @author zejian 
     * @time 2016年3月15日 下午2:05:43 
     * @decrition callable执行测试类 
     */  
    public class CallableTest {  
          
        public static void main(String[] args) {            
            //创建线程池  
            ExecutorService es = Executors.newSingleThreadExecutor();  
            //创建Callable对象任务  
            CallableDemo calTask=new CallableDemo();  
            //创建FutureTask  
            FutureTask<Integer> futureTask=new FutureTask<>(calTask);  
            //执行任务  
            es.submit(futureTask);  
            //关闭线程池  
            es.shutdown();  
            try {  
                Thread.sleep(2000);  
            System.out.println("主线程在执行其他任务");  
              
            if(futureTask.get()!=null){  
                //输出获取到的结果  
                System.out.println("futureTask.get()-->"+futureTask.get());  
            }else{  
                //输出获取到的结果  
                System.out.println("futureTask.get()未获取到结果");  
            }  
              
            } catch (Exception e) {  
                e.printStackTrace();  
            }  
            System.out.println("主线程在执行完成");  
        }  
    }  

    结果:

    Callable子线程开始计算啦!
    主线程在执行其他任务
    Callable子线程计算结束!
    futureTask.get()-->12497500
    主线程在执行完成
  • 相关阅读:
    事理学神器PDCA
    单元测试
    web框架学习路线
    编译器实现(三)
    markdown test
    设计模式
    编译器实现(二)
    编译器实现(一)
    操作系统结构
    emacs配置笔记(windows10)
  • 原文地址:https://www.cnblogs.com/L-a-u-r-a/p/8570080.html
Copyright © 2020-2023  润新知