美文网首页多线程高并发开发安卓开发博客java多线程
Java 多线程(三):Callable、Future、Futu

Java 多线程(三):Callable、Future、Futu

作者: 聪明的奇瑞 | 来源:发表于2018-03-11 00:11 被阅读54次

    无论是 Thread 或是 Runnable,在任务执行完成后无法获取返回结果

    • Callable 与 Runnable 区别:
      • Callable 接口能返回执行结果,而 Runnable 接口不能返回结果
      • Callable 接口的 call() 方法允许抛出异常,而 Runnable 接口的 run() 方法的异常只能在内部处理

    Callable、Future、FutureTask

    Callable

    • Java5 引入了 Callable,它能配合 Future 在任务执行完后获取执行结果
    • 该接口的定义如下,声明了一个 call() 方法,返回值为泛型,可抛出异常
    public interface Callable<V> {   
          V   call()   throws Exception;   
    }   
    

    Future

    • Future 接口是用来获取异步计算结果的,该接口声明了以下方法:
      • get():获取异步执行的结果,如果没有结果可用,此方法会阻塞到异步计算完成
      • isDone():如果任务执行结束,无论是否正常结束还是中途取消或发生异常,都返回 true
      • isCanceller():如果任务完成前被取消,则返回 true
      • cancel(boolean mayInterruptRunning)
        • 如果任务还没开始,执行 cancel(...) 则方法 false
        • 如果任务已经启动,执行 cancel(true) 将以中断执行此任务的方式来试图停止任务,如果停止成功返回 true
        • 执行 cancel(false) 方法不会对正在执行的任务线程产生影响,此时返回 false
        • 当任务执行完成,执行 cancel(...) 方法将返回 false

    FutureTask

    • FutureTask 是 Future 的实现,并且实现了 Runnable 接口,它有 3 种状态:
      • 未启动:FutureTask.run() 方法还未被执行之前
      • 已启动:FutureTask.run() 方法已被调用
      • 已完成:FutureTask.run() 方法已执行结束
    • 当 FutureTask 处于未启动或已启动状态时,如果我们执行 FutureTask.get() 方法将导致调用线程阻塞
    • 当 FutureTask 处于已完成状态时,执行 FutureTask.get() 方法将导致调用线程立即返回结果或者抛出异常
    • 当 FutureTask 处于未启动状态时,执行 FutureTask.cancel() 方法将导致此任务永远不会执行
    • 当 FutureTask 处于已启动状态时,执行 cancel(true) 方法将以中断执行此任务线程的方式来试图停止任务,如果任务取消成功,cancel(...) 返回 true
    • FutureTask 有两种构造函数
    public FutureTask(Callable<V> callable) {  
    }  
    public FutureTask(Runnable runnable, V result) {  
    }  
    

    代码例子

    • 例子一
    public class Main {
        public static void main(String[] args) {
            Callable<String> callable = new MyCallable();
            FutureTask<String> futureTask = new FutureTask<String>(callable);
            new Thread(futureTask).start();
            try {
                System.out.println(futureTask.get());
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            }
        }
    
        public static class MyCallable implements Callable<String> {
            public String call() throws Exception {
                Thread.sleep(1000);
                return "linyuan";
            }
        }
    }
    
    
    • 例子二
    public class Main {
        public static void main(String[] args) {
            ExecutorService executorService = Executors.newSingleThreadExecutor();
            Callable<String> callable = new MyCallable();
            Future future = executorService.submit(callable);
            try {
                System.out.println(future.get());
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            }
            executorService.shutdown();
        }
    
        public static class MyCallable implements Callable<String> {
            public String call() throws Exception {
                Thread.sleep(1000);
                return "linyuan";
            }
        }
    }
    
    

    相关文章

      网友评论

        本文标题:Java 多线程(三):Callable、Future、Futu

        本文链接:https://www.haomeiwen.com/subject/wcwvfftx.html