固然Runnable接口实现多线程比继承Thread类实现多线程来的好,但是Runnable接口里的run方法并不能返回操作结果。为了解决这样的矛盾,提供了Callable接口。
JUC工具包下的Callable接口
@FunctionalInterface
public interface Callable<V>{
public V call() throws Exceptionl;
}
call方法执行完成线程的主体功能之后(类似于Runnable的run方法)会返回值,而返回值类型由Callable接口上的泛型决定。
范例:定义一个线程主体类
class MyThread implements Callable<String>{
private int ticket=10;//这里的变量会压入局部变量表
@Override
public String call() throws Exception {
for (int i = 0; i < 100; i++) {
if(this.ticket>0){
System.out.println("sell,ticket="+this.ticket--);
}
}
return "ticket has sold out!";
}
}
此时发现我们的Thread类里面并没有提供支持Callable接口的多线程应用。
我们继续看JUC包下,JDK1.5以后有FutureTask<V>类,这个类主要是负责Callable接口对象操作,这个类的定义结构如下:
public class FutureTask<V> extends Object implements RunnableFuture<V>
而RunnableFuture接口继承了Runnable接口和Future接口
public interface RunnableFuture<V> extends Runnable,Future<V>
看JDK文档知道,Future接口有get方法
FutureTask类里有如下构造方法:
public FutureTask(Callable<V> callable)
接收Callable接口对象/继承了Callable接口对象的类,以此使得这个类能接收call方法的返回结果,从而放入值,而FutureTask又间接实现了Runnable接口和Future接口,Future接口的get方法负责取出值
完整的Callable接口实现多线程:
package TestDemo;
import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;
class MyThread implements Callable<String>{
private int ticket=10;//这里的变量会压入局部变量表
@Override
public String call() throws Exception {
for (int i = 0; i < 100; i++) {
if(this.ticket>0){
System.out.println("sell,ticket="+this.ticket--);
}
}
return "ticket has sold out!";
}
}
public class TestDemo{
public static void main(String[] args)throws Exception{
MyThread mt1=new MyThread();
MyThread mt2=new MyThread();
FutureTask<String> task1=new FutureTask<String>(mt1);//FutureTask构造方法接收Callable接口对象或其实现
FutureTask<String> task2=new FutureTask<String>(mt2);
//FutureTask是Runnable接口的实现类/子类,所以Thread构造方法能接收其对象
new Thread(task1).start();//多线程启动
new Thread(task2).start();//多线程启动
//FutureTask同时是Future接口的实现类/子类,父接口的get方法可以获取值
System.out.println("A:"+task1.get());
System.out.println("B:"+task2.get());
}
}
结果:
第三种方式的实现麻烦在于既要接收返回值信息,并且又要与原始的多线程的实现靠拢(Threadl类)
总结:
1.对于多线程的实现,重点在于Runnable和Thread类
2.Callable接口之后也会又诸多应用