对于一些需要线程完成某些计算,并返回计算结果的需求,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