11.Callable接口
Callable 接口类似于 Runnable,两者都是为那些其实例可能被另一个线程执行的类设计的。但是 Runnable 不会返回结果,并且无法抛出经过检查的异常。
特点:
1.Callable 可以抛出异常
2.Callable 可以返回结果
3.Callable 调用get方法时会阻塞
4.Callable 需要借助FutureTask 去和Thread关联启动
样例:
public class Juc_Test_Lock {
public static void main(String[] args) {
//重点1:创建Callable接口实例
MyThread myThread=new MyThread();
//重点2:创建Callable关联的FutureTask
FutureTask futureTask=new FutureTask(myThread);
new Thread(futureTask,"线程1").start();
//重点3:这个方法会阻塞,因为要等待线程执行完毕拿到结果
Integer result= (Integer) futureTask.get();
System.out.println("线程返回:"+result);
}
}
//重点4:实现Callable接口
class MyThread implements Callable<Integer>{
@Override
public Integer call() throws Exception {
System.out.println("call方法");
return 1024;
}
}
输出:
call方法
线程返回:1024
问题:如果是两个线程同时启动呢?
new Thread(futureTask,"线程1").start();
new Thread(futureTask,"线程2").start();
输出:发现也是调用了一次call方法,理由如下!
call方法
线程返回:1024
FutureTask的构造器如下:会有一个state去标记,如果执行了一次,这个状态会变化!下次就不会执行了
public FutureTask(Callable<V> callable) {
if (callable == null)
throw new NullPointerException();
this.callable = callable;
this.state = NEW; // ensure visibility of callable
}