对于一些需要线程完成某些计算,并返回计算结果的需求,java新的api提供了Callable接口,该接口返回线程的计算结果,结果以Futrue对象形式,为了支持业务代码能够根据需要等待线程完成计算或者取消任务,Future接口的get函数接口支持timeout
参数,即在timeout
时间内返回结果,否则抛出TimeoutException
异常;同时Future接口支持外围代码直接取消线程任务的功能,即cancel函数接口,cancel函数有一个boolean参数,如果为true,任务将被中断,否则将等待任务运行完毕再返回。
示例:
package pku.edu.cn; import java.util.LinkedList; import java.util.List; import java.util.Random; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; public class Future01 { public static void main(String[] args) throws InterruptedException, ExecutionException { ExecutorService pool = Executors.newFixedThreadPool(5); Future<?> future= pool.submit(new workThread()); Future<?> future2= pool.submit(new RunFuture()); try { System.out.println(future2.get(1, TimeUnit.MILLISECONDS));//等待很短时间,便于测试 } catch (InterruptedException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } catch (ExecutionException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } catch (TimeoutException e1) { // TODO Auto-generated catch block System.out.println("Timeout,no result will return."); } finally{ future2.cancel(true); //这里必须要cancel,否则任务仍然将运行,直到任务自然结束 } try { Thread.sleep(1000); future.cancel(true); System.out.println("Future cancelled."); } catch (InterruptedException e){ e.printStackTrace(); } System.out.println(future); if(future.isDone()&&!future.isCancelled()) System.out.println(future.get()); pool.shutdown(); //此pool必须被关闭,否则pool线程将继续运行,JVM不会退出 } } class workThread implements Callable<List<Integer>> { public List<Integer> call()throws Exception{ List<Integer> primes = new LinkedList<Integer>(); Integer p = 3; //!Thread.currentThread().isInterrupted()判断条件必须有,否则即使future被cancel, //线程任务也不会马上停止;特别是一些while(ture)风格的线程任务,外围代码完全不能cancel线程 while(p<1000000000&&!Thread.currentThread().isInterrupted()) { p = new Integer(getNextPrime(p)); primes.add(p); p++; } return primes; } public int getNextPrime(int n) { int nextPrime = n; for(int j=n; ; j++) { boolean isPrime = false; int stopNum = (int)(Math.sqrt(j)+1); //System.out.println(j+","+stopNum); for(int i=2; i<=stopNum; i++) { //System.out.println(j+"/"+i+"="+j/i); if(j%i == 0) break; if(i == stopNum) isPrime = true; } if(isPrime) { nextPrime = j; break; } } //System.out.println("Prime:"+nextPrime); return nextPrime; } } class RunFuture implements Callable<Integer>{ int i=0; @Override public Integer call() { while (i<100000&&!Thread.currentThread().isInterrupted()) { System.out.println("i++:"+i); i++; } return new Random().nextInt(); } }
执行结果(不同的运行结果不一样):
i++:0
i++:1
i++:2
... ...
i++:25
i++:26
i++:27
Timeout,no result will return.
Future cancelled.
java.util.concurrent.FutureTask@a59698