欢迎您访问365答案网,请分享给你的朋友!
生活常识 学习资料

【JUC并发编程07】Callable接口

时间:2023-08-01
文章目录

7 Callable接口

7.1 Callable接口创建线程7.2 FutureTask 7 Callable接口

创建线程的多种方式:

继承Thread类实现Runnable接口Callable接口线程池 7.1 Callable接口创建线程

目前学习了有两种创建线程的方法,一种是通过创建 Thread 类,另一种是通过使用 Runnable 创建线程,但是,Runnable 缺少的一项功能是,当线程终止时(即 run()完成时),我们无法使线程返回结果。为了支持此功能,Java 中提供了 Callable 接口

比较Runnable接口和Callable接口

Callable中的call()计算结果,如果无法计算结果,会抛出异常

Runnable中的run()使用实现接口Runnable的对象创建一个线程时,启动该线程将导致在独立执行的线程中调用该对象的run方法

总的来说:run()没有返回值,不会抛出异常。而call()有返回值,会抛出异常

因为Thread的构造函数中没有Callable接口的参数设置,直接替换不可以,只能用下面这种线程创建方法(找一个类,即和Runnable接口有关系,又和Callable接口有关系)

发现Runnable接口有实现类FutureTask(中间对象)

FutureTask的构造函数有Callable参数,通过FutureTask创建线程对象

使用 lambda 方式创建代码如下:

public class CallableTest { public static void main(String[] args) throws ExecutionException, InterruptedException { new Thread(()->{ System.out.println(Thread.currentThread().getName()+"执行Runnable"); }).start(); FutureTask task = new FutureTask<>(() -> { System.out.println(Thread.currentThread().getName() + "使用Callable接口"); return "Callable接口返回值"; }); new Thread(task).start(); System.out.println("Callable返回值:" + task.get()); }}

输出为:

Thread-0执行RunnableThread-1使用Callable接口Callable返回值:Callable接口返回值

详细代码可以参考如下代码

//比较 callable和runnable 的区别class MyThread1 implements Runnable{ @Override public void run() { //这里没有返回值 }}class MyThread2 implements Callable{ @Override public Object call() throws Exception { System.out.println(Thread.currentThread().getName()+"线程运行"); return "Callable 的实现线程"; //有返回值 }} public class diffentence { public static void main(String[] args) throws ExecutionException, InterruptedException { //创建 实现Runnable 的线程 new Thread( new MyThread1(),"t1" ).start(); //创建 实现Callable 的线程 不能直接替换 ,没有这个类型的构造方法 // new Thread( new MyThread2(),"t2" ).start(); //选择FutureTask 他是 Runnable 的实现类,而且构造方法含有Callable类型 FutureTask task = new FutureTask(new MyThread2()); new Thread(task,"hhh").start(); System.out.println("返回值"+task.get()); //调用里面的返回值 }}

7.2 FutureTask

进入FutureTask底层源码可以看到它的构造器

// 创建一个FutureTask,一旦运行就执行给定的Callablepublic FutureTask(Callable callable) { if (callable == null) throw new NullPointerException(); this.callable = callable; this.state = NEW; // ensure visibility of callable}// 创建一个FutureTask,一旦运行就执行给定的Ru你那边了,并安排成功完成时get返回给定的结果public FutureTask(Runnable runnable, V result) { this.callable = Executors.callable(runnable, result); this.state = NEW; // ensure visibility of callable}

其他常用的代码:

// get()获取结果public V get() throws InterruptedException, ExecutionException { int s = state; if (s <= COMPLETING) s = awaitDone(false, 0L); return report(s);}// outcome就是返回值private V report(int s) throws ExecutionException { Object x = outcome; if (s == NORMAL) return (V)x; if (s >= CANCELLED) throw new CancellationException(); throw new ExecutionException((Throwable)x);}

未来的任务,如果运行过一次,那么下一次,就直接得到结果

Copyright © 2016-2020 www.365daan.com All Rights Reserved. 365答案网 版权所有 备案号:

部分内容来自互联网,版权归原作者所有,如有冒犯请联系我们,我们将在三个工作时内妥善处理。