JUC—Callable接口
一、callable接口是什么?
面试题:
获得多线程的方法几种?
正确答案如下:
传统的 是继承thread类和实现runnable接口,
java5以后又有实现 callable接口 和 java的线程池获得
函数式接口
这是一个函数式接口,因此可以用作lambda表达式或方法引用的赋值对象 。
二、与runnable对比(实现方法对比)
面试题:callable接口与runnable接口的区别?
答:(1)是否有返回值
(2)是否抛异常
(3)落地方法不一样,一个是run,一个是call
创建新类MyThread实现runnable接口
class MyThread implements Runnable{
@Override
public void run() { }
}
新类MyThread2实现callable接口
class MyThread2 implements Callable<Integer>{
@Override
public Integer call() throws Exception {
return 200;
}
}
三、怎么用?
(1)直接替换runnable是否可行?
不可行,因为:thread类的构造方法根本没有Callable
这像认识一个不认识的同学,我可以找中间人介绍。
中间人是什么? java多态,一个类可以实现多个接口!!
FutureTask<Integer> ft = new FutureTask<Integer>( new MyThread());
new Thread( ft , "AA" ).start();
运行成功后如何获得返回值?
ft .get();
FutureTask
1、FutureTask是什么?
未来的任务,用它就干一件事,异步调用
main方法就像一个冰糖葫芦,一个个方法由main串起来。
但解决不了一个问题:正常调用挂起堵塞问题
例子:
( 1 )老师上着课,口渴了,去买水不合适,讲课线程继续,我可以单起个线程找班长帮忙买水,
水买回来了放桌上,我需要的时候再去 get 。
( 2 ) 4 个同学, A 算 1+20,B 算 21+30,C 算 31* 到 40,D 算 41+50 ,是不是 C 的计算量有点大啊,
FutureTask 单起个线程给 C 计算,我先汇总 ABD ,最后等 C 计算完了再汇总 C ,拿到最终结果
( 3 )高考:会做的先做,不会的放在后面做
2、原理
在主线程中需要执行比较耗时的操作时,但又不想阻塞主线程时,可以把这些作业交给Future对象在后台完成,
当主线程将来需要时,就可以通过Future对象获得后台作业的计算结果或者执行状态。
一般FutureTask多用于耗时的计算,主线程可以在完成自己的任务后,再去获取结果。
仅在计算完成时才能检索结果;如果计算尚未完成,则阻塞 get 方法。一旦计算完成,
就不能再重新开始或取消计算。get方法而获取结果只有在计算完成时获取,否则会一直阻塞直到任务转入完成状态,
然后会返回结果或者抛出异常。
只计算一次
get方法放到最后
3、代码
package demo1; import java.util.concurrent.*; class MyThread implements Runnable{
@Override
public void run() {
System.out.println("继承runnable方法");
}
}
class MyThread2 implements Callable<Integer>{ @Override
public Integer call() throws Exception{
System.out.println(Thread.currentThread().getName()+"come in callable");
return 200;
}
} public class Callablelearn {
public static void main(String[] args) throws Exception{
/**
* 建立futureTask (创建中间人) 介绍线程与callable认识,
*
*/
// FutureTask<Integer> futureTask = new FutureTask(new MyThread2());
FutureTask<Integer> futureTask = new FutureTask<>(()->{
System.out.println(Thread.currentThread().getName()+"come in callable"); return 1024;
});
FutureTask<Integer> futureTask2 = new FutureTask<>(()->{
System.out.println(Thread.currentThread().getName()+"come in callable"); return 2048;
});
new Thread(futureTask,"zhangsan").start();
new Thread(futureTask2,"lisi").start();
while(!futureTask.isDone()){
System.out.println("------wait"); }
System.out.println(futureTask.get());
System.out.println(Thread.currentThread().getName()+"come over");
}
/**
* 在主线程中需要执行比较耗时的操作时,但又不想阻塞主线程时,可以把这些作业交给Future对象在后台完成,
* 当主线程将来需要时,就可以通过Future对象获得后台作业的计算结果或者执行状态。
*
* 一般FutureTask多用于耗时的计算,主线程可以在完成自己的任务后,再去获取结果。
*
* 仅在计算完成时才能检索结果;如果计算尚未完成,则阻塞 get 方法。一旦计算完成,
* 就不能再重新开始或取消计算。get方法而获取结果只有在计算完成时获取,否则会一直阻塞直到任务转入完成状态,
* 然后会返回结果或者抛出异常。
*
* 只计算一次
* get方法放到最后
*/
}
最新文章
- Java集合类学习笔记(List集合)
- android: SQLite更新数据
- DataSet导出到Excel,并生成文件(C#实现,可合并行和列)
- ip
- winform学习-----理解小概念-20160518
- c#读取文本文档实践1-File.ReadAllLines()
- [Hibernate 2]session的三种状态
- 待验证的一些IOS问题
- spring data jpa入门学习
- Windows Live Writer的Markdown插件MarkdownInLiveWriter支持语法高亮了
- vs2013内置IISExpress相关问题
- Get https://registry-1.docker.io/v2/: net/http: request canceled while waiting for connection (Clien
- CSS 基础:CSS 工作原理(2)<;思维导图>;
- mybaits拦截器+自定义注解
- luoguP1368 工艺(最小表示法 后缀自动机)
- leetcode1019
- swift:简单使用翻页控制器UIPageViewController
- hdu 2476 区间dp
- asp.net mvc全局异常捕获
- word中手动添加endnote的加载项