Runnable

Runnable接口非常简单,就定义了一个办法run(), 实现Runnable接口的run办法就能够实现多线程
// 函数式接口@FunctionalInterfacepublic interface Runnable {    public abstract void run();}

Callable

很多人都晓得要想在多线程中获取异步返回值后果个别是用Callable和FutureTask接口来配合实现,但可能很多人都不晓得其实Callable是依赖于Runnable的run办法进行执行工作的,而后在通过FutureTask来收集返回值后果,上面咱们就本人模仿写一份FutureTask代码来看看是怎么实现的吧。
 /** * @author yinfeng * @description  本人实现futureTask,基于park/unpark进行线程通信 * @since 2022/1/9 21:32 */public class MyFutureTask<T> implements Runnable {     Callable<T> callable;    /**     * callable执行后果     */    T result;    /**     * task执行状态     */    String state = "new";    /**     * 存储正在期待的消费者     */    LinkedBlockingQueue<Thread> waiters = new LinkedBlockingQueue<>();    public MyFutureTask(Callable<T> callable) {        this.callable = callable;    }    @Override    public void run() {        try {            result = callable.call();        } catch (Exception e) {            e.printStackTrace();        } finally {            state = "end";        }        // 工作执行实现后通过unpark告诉消费者        System.out.println(Thread.currentThread().getName() + " 生产者执行完结,告诉消费者");        while (true) {            Thread waiter = waiters.poll();            if (waiter == null) {                break;            }            LockSupport.unpark(waiter);        }    }    /**     * park / unpark     */    public T get() throws Exception {        Thread mainThread = Thread.currentThread();        // 塞入期待的汇合中        waiters.add(mainThread);         // 判断状态        System.out.println(Thread.currentThread().getName() + " 消费者进入期待");        while (!"end".equals(state)) {            // 阻塞期待工作执行实现后告诉            LockSupport.park(mainThread);        }        return result;    }}

咱们写个demo测试一下

/** * @author yinfeng * @description * @since 2022/1/9 21:32 */public class FutureTaskTest {    public static void main(String[] args) throws Exception {        final MyFutureTask<String> futureTask = new MyFutureTask<>(() -> {            Thread.sleep(5000);            return "工作实现888";        });        new Thread(futureTask).start();        final String result = futureTask.get();        System.out.println("后果:"+result);        // 控制台打印如下:         // main 消费者进入期待        // Thread-0 生产者执行完结,告诉消费者        // 后果:工作实现888    }}
能够看到咱们的demo也是失常运行的,所以很要害的一点还是Callable是依赖于Runnable的run办法进行执行工作的