juc笔记之callable详解

一、Callable是什么

它是一个接口,位于juc包下,代表一个异步的任务,在多线程环境下,使用callable更明智,因为有些时候,我们也许需要获取方法的执行结果,或者得到异常信息,那么使用callable接口要比使用runnable接口来的方便的多。

callable接口里面最重要的一个方法是call()方法,它能够自定义返回值类型,也可以抛出异常,以便程序员看到发生了什么错误。

那下面来看下如何使用callable接口吧。

二、使用步骤

1.自定义类实现callable接口

//范型的意思是作用于方法的返回值。
class MyThread implements Callable<Integer> {
    
    
    @Override
    public Integer call() {
    
    
        System.out.println("call()"); // 会打印几个call
        // 耗时的操作
        return 1024;
    }
}

2.测试

package com.lhh.callable;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

public class CalableDemo  {
    
    
    public static void main(String[] args) throws ExecutionException, InterruptedException {
    
    
        // new Thread(new Runnable()).start();
        // new Thread(new FutureTask<V>()).start();
        // new Thread(new FutureTask<V>( Callable )).start();
        new Thread().start(); // 怎么启动Callable

        MyThread thread = new MyThread();
        FutureTask futureTask = new FutureTask(thread); // 适配类,可以把它理解为中间商,通过它来联系runnable,因为Thread构造接受的参数为runnable接口。

        new Thread(futureTask,"A").start();
        new Thread(futureTask,"B").start(); // 结果会被缓存,效率高

        //这个get 方法可能会产生阻塞!把他放到最后,假如任务里面是一个非常耗时的操作,那么要等到这个耗时的操作执行完毕之后才能拿到结果。
        Integer o = (Integer) futureTask.get(); 
        System.out.println(o);
    }
}

执行结果如下:
在这里插入图片描述
咦,很奇怪,我明明开启了两条线程执行任务的呀,怎么突然变成只能看到一个线程的执行结果呢?

这里其实是一个小细节,因为这里面是有缓存的,第一次的执行结果会被缓存起来,等你下次在执行相类似的操作的时候,直接从缓存里面拿就可以了,也就是不再执行call()方法了。

三、总结

callable的讲解到此结束,主要记住它的作用是用来处理多线程下的任务执行的,跟runnable的作用相同,但是它有它的优势

  • 方法有返回值
  • 方法可以抛出异常

runnable使用run方法执行任务,callable使用call()方法执行任务

记住在使用callable的过程当中,需要借助"中间商"FutureTask来连接。

猜你喜欢

转载自blog.csdn.net/qq_41486775/article/details/113386537