Java多线程详解(七)------Callable接口介绍

一、与runnable接口对比

 1  创建新类MyThread实现runnable接口
 2 class MyThread implements Runnable{
 3  @Override
 4  public void run() {
 5  
 6  }
 7 }
 8 新类MyThread2实现callable接口
 9 class MyThread2 implements Callable<Integer>{
10  @Override
11  public Integer call() throws Exception {
12   return 200;
13  } 
14 }
15  面试题:callable接口与runnable接口的区别?
16  
17  答:(1)是否有返回值
18        (2)是否抛异常
19        (3)落地方法不一样,一个是run,一个是call
20  
21  
22  
23  

二、如何使用

 

 不可行,因为:thread类的构造方法根本没有Callable

FutureTask<Integer> ft = new FutureTask<Integer>(new MyThread());
new Thread(ft, "AA").start();

运行成功后如何获得返回值?

 ft.get();

三、FutureTask

是什么

未来的任务,用它就干一件事,异步调用
main方法就像一个冰糖葫芦,一个个方法由main串起来。
但解决不了一个问题:正常调用挂起堵塞问题

在主线程中需要执行比较耗时的操作时,但又不想阻塞主线程时,可以把这些作业交给Future对象在后台完成,
当主线程将来需要时,就可以通过Future对象获得后台作业的计算结果或者执行状态。

一般FutureTask多用于耗时的计算,主线程可以在完成自己的任务后,再去获取结果。

仅在计算完成时才能检索结果;如果计算尚未完成,则阻塞 get 方法。一旦计算完成,
就不能再重新开始或取消计算。get方法而获取结果只有在计算完成时获取,否则会一直阻塞直到任务转入完成状态,
然后会返回结果或者抛出异常。

只计算一次
get方法放到最后

代码:

 1 package com.study.callable;
 2 
 3 
 4 import java.util.concurrent.Callable;
 5 import java.util.concurrent.FutureTask;
 6 import java.util.concurrent.TimeUnit;
 7 
 8 class MyThread implements Runnable {
 9     @Override
10     public void run() {
11     }
12 }
13 
14 class MyThread2 implements Callable<Integer> {
15     @Override
16     public Integer call() throws Exception {
17         System.out.println(Thread.currentThread().getName() + " come in callable");
18         return 200;
19     }
20 }
21 
22 public class CallableDemo {
23     public static void main(String[] args) throws Exception {
24 //        FutureTask<Integer> futureTask = new FutureTask<>(new MyThread2());
25 //        new Thread(futureTask,"zhang3").start();//传入futureTask对象
26 //        System.out.println(futureTask.get());
27 //
28         FutureTask<Integer> ft1 = new FutureTask(() -> {
29             System.out.println(Thread.currentThread().getName() + " come in callable");
30             TimeUnit.SECONDS.sleep(4);
31             return 1024;
32         });
33         FutureTask<Integer> ft2 = new FutureTask(() -> {
34             System.out.println(Thread.currentThread().getName() + " come in callable");
35             TimeUnit.SECONDS.sleep(4);
36             return 2048;
37         });
38         //启动线程
39         new Thread(ft1, "zhang3").start();
40         new Thread(ft2, "li4").start();
41 
42         System.out.println(ft1.get());
43         System.out.println(ft2.get());
44 
45         /**
46          *
47          *
48          在主线程中需要执行比较耗时的操作时,但又不想阻塞主线程时,可以把这些作业交给Future对象在后台完成,
49          当主线程将来需要时,就可以通过Future对象获得后台作业的计算结果或者执行状态。
50 
51          一般FutureTask多用于耗时的计算,主线程可以在完成自己的任务后,再去获取结果。
52 
53          仅在计算完成时才能检索结果;如果计算尚未完成,则阻塞 get 方法。一旦计算完成,
54          就不能再重新开始或取消计算。get方法而获取结果只有在计算完成时获取,否则会一直阻塞直到任务转入完成状态,
55          然后会返回结果或者抛出异常。
56 
57          只计算一次
58          get方法放到最后
59          */
60     }
61 }
原文地址:https://www.cnblogs.com/zsy-code/p/13781639.html