一、与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 }