用运场景 多个任务串行执行,有一个任务耗时较久,可以作为单独的任务独立执行,或需要返回值的场景,支付等等。
区别
1.Callable接口有异常抛出,Runnable接口没有。
2.Callable接口有返回值,Runnable接口没有
如何使用
FutureTask类继承RunnableFuture接口继承Runnable接口
FutureTask类有构造方法
public FutureTask(Callable<V> callable) { if (callable == null) throw new NullPointerException(); this.callable = callable; this.state = NEW; // ensure visibility of callable }
我们发现新建Thread类时并没有传Callable类的参数,我们这个时候再怀疑是否sun公司设计缺陷,其实不是的,FutureTask是基于这种思想,现实工程中有好多类implements了一堆的接口,这是一种设计思想,相当于拿到了通行证,也就是他自身也有Runnable接口的run方法,又增加了Callable接口的call方法。
package com.example.demo; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.FutureTask; import java.util.concurrent.TimeUnit; class MyThread implements Callable<Integer> { @Override public Integer call() throws Exception { System.out.println(Thread.currentThread().getName()+" ***********come in Callable"); // 暂停一会儿线程 try { TimeUnit.SECONDS.sleep(3); }catch (InterruptedException e){ e.printStackTrace(); } return 1024; } } /** * @author chenxf * @create 2021-08-08 9:00 */ public class CallableDemo { public static void main(String[] args) throws ExecutionException, InterruptedException { // 两个线程,一个main主线程,一个是AAfutureTask // FatureTask(Callable<V> callable) FutureTask<Integer> futureTask = new FutureTask<>(new MyThread()); FutureTask<Integer> futureTask2 = new FutureTask<>(new MyThread()); new Thread(futureTask, "AA").start(); new Thread(futureTask, "BB").start(); System.out.println(Thread.currentThread().getName()+"****************"); int result01 = 100; // while(!futureTask.isDone()){ // // } int result02 = futureTask.get();// 要求获得Callable线程的计算结果,如果没有计算完成就会一直等待造成阻塞,只到计算完成 System.out.println("*****result:" + (result01 + result02)); } }