使用Callable接口实现多线程
在Runnable接口实现的多线程会出现Runnable接口中的run()方法不能返回操作结果的问题,Callable接口即是用来解决在这个问题
接口的定义:
publlic interface Callable<V>{
public V call() throws Exception;
}
call()方法返回的类型由Calable接口上的泛型类型动态决定。
由于Thread类中并没有定义任何构造方法可以直接接收Callable接口对象实例,并且由于需要接收call()方法返回值的问题,所以从JDK1.5开始提供有一个java.until.concurrent.FutureTask类。
此类定义:
public class FutureTask<V> extends Object
implements RunnableFuture<V>
其中RunnableFuture接口实现了Future与Runnable接口
表 FutureTask类的常用方法:
方法 | 类型 | 描述 |
---|---|---|
public FetureTask(Callable callable) | 构造 | 接收Callable接口实例 |
public FutureTask(Runnable runnable,V result) | 构造 | 接收Runnable实例,并指定返回结果类型 |
public V get() throws InterruptedException,ExecutionException | 普通 | 取得线程操作结果,此方法为Future接口定义 |
通过FutureTask类的继承结构可以发现其为Runnable接口的子类,并且FutureTask类可以接收Callable接口实例,这样依然可以利用Thread类来实现多线程的启动,而如果想要接收返回结果,则利用Future接口中的get()方法即可。
例、
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
class MyThread implements Callable<String>{
private int ticket=5;
public String call() throws Exception{
for(int x=0;x<100;x++){
if(this.ticket>0){
System.out.println("卖票,ticket="+this.ticket--);
}
}
return "票已卖光!";
}
}
public class Demo{
public static void main(String[] args){
MyThread mt1=new MyThread();
MyThread mt2=new MyThread();
FutureTask<String> task1=new FutureTask<String>(mt1);
FutureTask<String> task2=new FutureTask<String>(mt2);
new Thread(task1).start();
new Thread(task2).start();
try {
System.out.println("A线程返回结果:"+task1.get());
System.out.println("B线程返回结果:"+task2.get());
} catch (InterruptedException | ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
卖票,ticket=5
卖票,ticket=5
卖票,ticket=4
卖票,ticket=4
卖票,ticket=3
卖票,ticket=3
卖票,ticket=2
卖票,ticket=1
卖票,ticket=2
卖票,ticket=1
A线程返回结果:票已卖光!
B线程返回结果:票已卖光!