JUC学习笔记-05-走进Callable

Runnable与Callable的区别

我们知道,创建线程的方式可以通过Thread类,Runnable接口,和Callable接口三种方式。其中Runnable和Callable是作为任务存在的。它们区别如下:

1、是否有返回值
Runnable 没有返回值,Callable有返回值
2、是否跑出异常
Runnable 没有异常,Callable有异常
3、方法不同, run(),call()
Runnable 运行的方法是run,Callable运行的方法是call

Runnable的使用方式

public class Test {
    public static void main(String[] args) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println(1);
            }
        }).start();
    }
}

Runnable直接作为Thread的参数,里面执行着线程任务。而Callable不同,它不能直接作为Thread的参数new出来,那么我们通过什么方式使用Callable呢?

Callable的使用方式

使用Callable

  • 使用Callable需要一个中间件,而这个中间件便是FutureTask,它是Runnable接口的一种实现类,故它的使用方式和Runnable一样都是作为Thread的参数,而Callable则作为FutureTask的参数,这样便通过FutureTask将Callable和Thread连接起来。

Callable的优点

  • 缓存: 结果缓存!效率提高N倍
    结果获取会阻塞:task.get() 获取值的方法一般放到最后,保证程序平稳运行的效率,因为他会阻塞等待结果产生!
public class CallableTest {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        //开启10个线程执行任务
        for (int i = 1; i < 10; i++) {
            //创建线程任务FutureTask
            FutureTask<Integer> futureTask = new FutureTask<>(new Callable<Integer>() {
                @Override
                public Integer call() throws Exception {
                    System.out.println("call()");
                    return 1024;
                }
            });
            // 放入Thread中使用,结果会被缓存,第一个参数是FutureTask任务,第二个参数是线程的名字
            new Thread(futureTask,String.valueOf(i)).start();
            // 这个get方法可能会被阻塞,如果在call方法中是一个耗时的方法,所以一般情况我们会把这个放在最后,或者使用异步通信
            int result = futureTask.get();
            System.out.println("返回值:" + result);
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值