JAVA并发编程——Callable、Future和FutureTask

无论是从类Thread继承还是实现Runnable接口来创建线程,方法run是没有返回值的 。线程可不可以有一个返回值?答案是肯定的。带返回值的线程可以通过接口Callable来定义,并通过接口Future来获得线程的返回值。

接口Callable

public interface Callable<V> {
    /**
     * Computes a result, or throws an exception if unable to do so.
     *
     * @return computed result
     * @throws Exception if unable to compute a result
     */
    V call() throws Exception;
}

Callable中有一个call()函数,call()函数有返回值。可以看到,这是一个泛型接口,call()函数返回的类型就是客户程序传递进来的V类型。这里只定义了线程会有返回值,其返回值是通过Future来获得的。

接口Future

接口Future允许在未来某个时间获得线程运行的结果,它保存了使用Callable接口定义的线程异步运行结果。当启动一个Future对象后,相当于启动了一个计算,然后可以去做别的事,Future对象的计算结果将在计算好后得到。

在Future接口中声明了如下5个方法:

public interface Future<V> {

    boolean cancel(boolean mayInterruptIfRunning);

    boolean isCancelled();
    
    boolean isDone();

    V get() throws InterruptedException, ExecutionException;

    V get(long timeout, TimeUnit unit)
        throws InterruptedException, ExecutionException, TimeoutException;
}

cancel方法:用来取消任务,如果取消任务成功则返回true,如果取消任务失败则返回false。参数mayInterruptIfRunning表示是否允许取消正在执行却没有执行完毕的任务,如果设置true,则表示可以取消正在执行过程中的任务。如果任务已经完成,则无论mayInterruptIfRunning为true还是false,此方法肯定返回false,即如果取消已经完成的任务会返回false;如果任务正在执行,若mayInterruptIfRunning设置为true,则返回true,若mayInterruptIfRunning设置为false,则返回false;如果任务还没有执行,则无论mayInterruptIfRunning为true还是false,肯定返回true。

isCancelled方法:表示任务是否被取消成功,如果在任务正常完成前被取消成功,则返回 true。
isDone方法:表示任务是否已经完成,若任务完成,则返回true;

get()方法:用来获取执行结果,这个方法会产生阻塞,会一直等到任务执行完毕才返回;

get(long timeout, TimeUnit unit)方法:用来获取执行结果,如果在指定时间内,还没获取到结果,就直接返回null。

也就是说Future提供了三种功能:
  1)判断任务是否完成;
  2)能够中断任务;
  3)能够获取任务执行结果。

因为Future只是一个接口,所以是无法直接用来创建对象使用的,因此就有了下面的FutureTask。

FutureTask

public class FutureTask<V> implements RunnableFuture<V> {}
public interface RunnableFuture<V> extends Runnable, Future<V> {}

FutureTask包装器同时实现了接口Runnable和接口Future,他可以很方便地对Callable对象进行封装并转换成Future对象,FutureTask的构造方法定义如下:

public FutureTask(Callable<V> callable) {
}
public FutureTask(Runnable runnable, V result) {
}

实例演示

public class UseFuture {
	
	
	/*实现Callable接口,允许有返回值*/
	private static class UseCallable implements Callable<Integer>{
		private int sum;
		@Override
		public Integer call() throws Exception {
			System.out.println("Callable子线程开始计算!");  
			Thread.sleep(2000);
	        for(int i=0 ;i<5000;i++){  
	            sum=sum+i;  
	        }  
	        System.out.println("Callable子线程计算结束!结果为: "+sum);  
	        return sum; 
		}
	}
	
	public static void main(String[] args) 
			throws InterruptedException, ExecutionException {
		
		UseCallable useCallable = new UseCallable();
		FutureTask<Integer> futureTask //用FutureTask包装Callable
			= new FutureTask<>(useCallable);
		new Thread(futureTask).start();//交给Thread去运行
		Random r = new Random();
		Thread.sleep(1000);
		if(r.nextBoolean()) {//用随机的方式决定是获得结果还是终止任务
			System.out.println("Get UseCallable result = "+futureTask.get());
		}else {
			System.out.println("中断计算。  ");
			futureTask.cancel(true);
		}
		
	}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值