有返回值的多线程的实现:FutureTask+Callable

来源:互联网 发布:b2轰炸机知乎 编辑:程序博客网 时间:2024/05/22 02:18

FutureTask类是Future 的一个实现,并实现了Runnable,所以可通过Excutor(线程池) 来执行,也可传递给Thread对象执行。

1 FutureTask类实现了RunnableFuture接口
public class FutureTask<V> implements RunnableFuture<V>
   
2 public interface RunnableFuture<V> extends Runnable, Future<V> {
    void run();
}

可以看出RunnableFuture继承了Runnable接口和Future接口,而FutureTask实现了RunnableFuture接口。所以它既可以作为Runnable被线程执行,又可以作为Future得到Callable的返回值

Callable接口则提供了一种有返回值的多线程实现方法,callable接口执行完成后FutureTask回调done()方法,同时FutureTask可以通过get()方法获得callable接口的返回值。


package com.java.test.futuretask;/** * 我们先来看一下FutureTask的实现:1 FutureTask类实现了RunnableFuture接口public class FutureTask<V> implements RunnableFuture<V>   2public interface RunnableFuture<V> extends Runnable, Future<V> {    void run();}可以看出RunnableFuture继承了Runnable接口和Future接口,而FutureTask实现了RunnableFuture接口。所以它既可以作为Runnable被线程执行,又可以作为Future得到Callable的返回值。 *  *  */import java.util.concurrent.Callable;import java.util.concurrent.ExecutionException;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.FutureTask;public class Test {public static void main(String[] args) {ExecutorService executor = Executors.newCachedThreadPool();   // 线程池for (int i = 0; i < 5; i++) {Callable<VideoInfo> c = new TaskCallable();MyFutureTask ft = new MyFutureTask(c);executor.submit(ft);  // 执行子线程System.out.println("this is main thread...");   // 主线程继续执行}executor.shutdown(); // 不再往线程池中加入新的执行对象}}/** * FutureTask类是Future 的一个实现,并实现了Runnable,所以可通过Excutor(线程池) 来执行,也可传递给Thread对象执行。 * callable接口执行完成后回调done()方法,同时可以通过get()方法获得callable接口的返回值 * */class MyFutureTask extends FutureTask<VideoInfo> {public MyFutureTask(Callable<VideoInfo> callable) {super(callable);}@Overrideprotected void done() {    //try {System.out.println("MyFutureTask done() : "+get()); } catch (InterruptedException | ExecutionException e) {e.printStackTrace();}}@Overridepublic VideoInfo get() throws InterruptedException, ExecutionException {System.out.println("这里面可以修饰一下返回结果。。。");VideoInfo videoInfo =  super.get();videoInfo.setName(videoInfo.getName() + "_??");return videoInfo;}}/** * Callable接口则提供了一种有返回值的多线程实现方法. * */class TaskCallable implements Callable<VideoInfo> {private String threadName;public TaskCallable(String threadName){this.threadName = threadName;}public TaskCallable(){}@Overridepublic VideoInfo call() throws Exception {Thread.currentThread().sleep(3000);VideoInfo videoInfo = new VideoInfo();videoInfo.setId("adfad");videoInfo.setName("name");videoInfo.setThreadName("线程名称 :" + Thread.currentThread().getName());return videoInfo;}}class VideoInfo {private String name;/** * @return the name */public String getName() {return name;}/** * @param name the name to set */public void setName(String name) {this.name = name;}/** * @return the id */public String getId() {return id;}/** * @param id the id to set */public void setId(String id) {this.id = id;}private String id;private String threadName;/** * @return the threadName */public String getThreadName() {return threadName;}/** * @param threadName the threadName to set */public void setThreadName(String threadName) {this.threadName = threadName;}@Overridepublic String toString() {return "VideoInfo [name=" + name + ", id=" + id +  ", threadName=" + threadName+"]";}}




0 0