8. JUC-Callable

与Runnable对比

class MyThread implements Runnable{
    @Override
    public void run() {
        
    }
}

class MyThread2 implements Callable<Integer>{
    @Override
    public Integer call() throws Exception {
        return null;
    }
}

两者有什么区别?

  1. 方法名不同
  2. 是否有返回值
  3. 是否抛异常

使用

image-20201212152609529

*newThread时,发现无法使用Callable直接替换Runnable,只能寻找将两个关联在一起的中间类,实现了Runnable接口的子接口RunnableFuture下,有一个FutureTask的类,这个类中有一个FutureTask(Callable<V> callable)的构造方法,就是它将Runnable与Callable连在了一起。

public class CallableDemo{
	public static void main(String[] args) throws Exception{
		FutureTask f = new FutureTask(new MyThread());
		new Thread(f,"A").start();
		// 获取返回值
		System.out.println(f.get());
	}
}

class MyThread implements Callable<Integer>{
	@Override
	public Integer call() throws Exception{
		System.out.println("test");
		return 1024;
	}
}

例子

(1)老师上着课,口渴了,自己去买水不合适,耽误讲课,但是可以找班长帮忙买水,过了一会,班长把水买回来了,这期间老师既没耽误讲课,又把喝水的问题解决了。
(2)4个同学,A算1+20,B算21+30,C算31*到40,D算41+50,因为C的计算量有点过大,如果执意等它,则会耽误其它的运算,此时FutureTask单起个线程给C计算,主线程先算ABD,最后等C计算完了再返回到主线程,这期间既没在C上面多花时间,又得到了ABD的运算结果。

解析

  1. 在主线程中需要执行比较耗时的操作时,但又不想阻塞主线程时,可以把这些作业交给Future对象在后台完成,当主线程将来需要时,就可以通过Future对象获得后台作业的计算结果或者执行状态。

  2. 一般FutureTask多用于耗时的计算,主线程可以在完成自己的任务后,再去获取结果。

  3. get方法只能在计算完成时获取结果,也就是放在当前方法中的最后一行,否则会一直阻塞,直到任务转入完成状态,然后返回结果或者抛出异常。

  4. 一个FutureTask只能供线程调用一次,当其他线程再次调用时,因为是一个对象,所以会直接使用之前的结果

*已经有Runnable接口,为什么还要出现Callable接口?请你谈谈它的诞生的前身背景?

  1. 因为并发,异步导致Callable接口的出现
  2. 主要是用Callable能够实现当多个任务执行时,若有一个任务耗时较长,可以把这个任务放到后台执行,主线程先完成其他任务,最后再等后台的任务结束,再一起进行总的计算。
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值