diff --git a/s-day06/src/com/inmind/thread_runnable02/Demo03.java b/s-day06/src/com/inmind/thread_runnable02/Demo03.java new file mode 100644 index 0000000..735967e --- /dev/null +++ b/s-day06/src/com/inmind/thread_runnable02/Demo03.java @@ -0,0 +1,59 @@ +package com.inmind.thread_runnable02; + +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.FutureTask; + +/* +我们主线程是否可以获取子线程运行结束后的执行结果??? +可以,使用Callable,配合FutureTask类来启动线程。 + + +FutureTask 是Runnable的实现类,FutureTask构造方法接收Callable对象,通过FutureTask作为参数传给Thread, +就可以将Callable接口实现类作为Thread的目标任务去执行 + + +代码说明: +FutureTask 实现了 Runnable 接口,因此可以作为 Thread 的构造参数 +FutureTask 构造函数接收 Callable 对象,从而将 Callable 与 Thread 关联起来 +调用 Thread.start() 启动线程,本质是执行 Callable 的 call() 方法 +通过 futureTask.get() 方法获取 call() 的返回值(该方法会阻塞直到结果返回) +总结: +Callable 可以与线程池配合使用(推荐,更高效的线程管理) +Callable 也可以通过 FutureTask 包装后直接交给 Thread 执行 +无论哪种方式,Callable 的核心价值都是:能返回结果 + 能抛出受检异常,这是它与 Runnable 的主要区别 +在实际开发中,更推荐使用线程池来管理 Callable 任务,因为线程池可以更好地控制线程数量、复用线程,避免频繁创建销毁线程带来的性能开销。 + */ +public class Demo03 { + public static void main(String[] args) { + //1.创建callable实现类对象 + MyCallableImpl myCallable = new MyCallableImpl(); + //2.使用FutureTask包装Callable + FutureTask futureTask = new FutureTask<>(myCallable); + //3.创建线程对象 + Thread thread = new Thread(futureTask); + thread.start();//此次启动线程,会自动调用call方法 + + //获取callable任务的执行结果 + System.out.println("等待任务执行结果...."); + try { + Integer result = futureTask.get();//阻塞方法,等待子线程的结果返回 + System.out.println("callable任务执行结果:"+result);//100 + } catch (InterruptedException e) { + e.printStackTrace(); + } catch (ExecutionException e) { + e.printStackTrace(); + } + + } +} + +class MyCallableImpl implements Callable{ + + @Override + public Integer call() throws Exception { + System.out.println("callable任务开始执行了,线程名:"+Thread.currentThread().getName()); + Thread.sleep(2000); + return 100; + } +}