常用的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 "); } }