常用的Thread类在run方法执行完之后是没有返回值的,要实现子线程完成任务后返回值给主线程需要借助第三方转存。Callable接口则提供了一种有返回值的多线程实现方法。 在这里,我们使用FutureTask来实现某种比较耗时的计算,当调用get时如果任务计算完成就会立即返回结果,否则get将阻塞直到任务完成状态。
package Observer;
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;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
public class MyFutureTask {
public static void main(String[] args) {
ExecutorService executorService= Executors.newCachedThreadPool();
FutureTask<String> task=new FutureTask<String>(new Callable<String>() {
public String call() throws Exception {
Thread.sleep(5*1000);
return "call ok";
}
});
//executorService.execute(task);
executorService.submit(task);//可以提交多个异步任务
long t = System.currentTimeMillis();
try {
String result = task.get(6000, TimeUnit.MILLISECONDS); //取得结果,同时设置超时执行时间为5秒。
System.out.println(result);
System.out.println("fuck");
result = task.get(); //取得结果,同时设置超时执行时间为5秒。
System.err.println("result is " + result + ", time is " + (System.currentTimeMillis() - t));
} catch (InterruptedException e) {
task.cancel(true);
System.err.println("Interrupte time is " + (System.currentTimeMillis() - t));
} catch (ExecutionException e) {
task.cancel(true);
System.err.println("Throw Exception time is " + (System.currentTimeMillis() - t));
} catch (TimeoutException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
executorService.shutdown();
}
}
}
package Observer;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask;
import java.util.concurrent.TimeUnit;
public class FutureTaskExample {
static class MyCallable implements Callable<String> {
private long waitTime;
public MyCallable(int timeInMillis) {
this.waitTime = timeInMillis;
}
@Override
public String call() throws Exception {
Thread.sleep(waitTime);
// return the thread name executing this callable task
return Thread.currentThread().getName();
}
}
public static void main(String[] args) {
MyCallable callable1 = new MyCallable(2000);
MyCallable callable2 = new MyCallable(8000);
FutureTask<String> futureTask1 = new FutureTask<String>(callable1);
FutureTask<String> futureTask2 = new FutureTask<String>(callable2);
ExecutorService executor = Executors.newFixedThreadPool(2);
executor.execute(futureTask1);
executor.execute(futureTask2);
while (true) {
try {
if(futureTask1.isDone() && futureTask2.isDone()){
System.out.println("all Done");
//shut down executor service
executor.shutdown();
return;
}
//wait indefinitely for future task to complete
System.out.println("FutureTask1 output="+futureTask1.get());
System.out.println("Waiting for FutureTask2 to complete");
String s = futureTask2.get(10000L, TimeUnit.MILLISECONDS);
if(s !=null){
System.out.println("FutureTask2 output="+s);
}
} catch(Exception e){
e.printStackTrace();
}
}
}
}
package Observer;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
public class FutureTest {
public static void main(String[] args) {
Preloader preloader = new Preloader();
preloader.start();
List<String> datas = null;
datas = preloader.getDatas();
for (String str : datas) {
System.out.println(str);
}
}
}
class Preloader {
private Callable<List<String>> callable = new Callable<List<String>>() {
@Override
public List<String> call() throws Exception {
return downloadData();
}
};
private Thread thread;
private FutureTask<List<String>> future;
private List<String> downloadData() {
List<String> list = new ArrayList<String>();
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
for (int i = 0; i < 10; i++) {
list.add("data" + i);
}
return list;
}
private void init() {
future = new FutureTask<List<String>>(callable);
thread = new Thread(future);
}
public Preloader() {
init();
}
public void start() {
thread.start();
}
public List<String> getDatas() {
try {
return future.get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
return null;
}
}
SwingWorker
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package com.jiepu.docbuildermanager.demo;
import javax.swing.SwingWorker;
/**
*
* @author Administrator
*/
public class TestThread {
public static void main(String[] args) throws Exception {
SwingWorker worker=new SwingWorker<Object, Object>() {
@Override
protected Object doInBackground() throws Exception {
System.out.println("老子是异步线程 来高我啊");
Thread.sleep(1000);
return System.getProperties();
}
};
worker.execute();
//不用等待异步线程执行完成
System.out.println("ok");
//等待异步线程执行完成
System.out.println(worker.get());
System.out.println("main thread finish ");
}
}