1、Callable源码:
package java.util.concurrent;
/**
* A task that returns a result and may throw an exception.
* Implementors define a single method with no arguments called
* call.
*
* The Callable interface is similar to {
* java.lang.Runnable}, in that both are designed for classes whose
* instances are potentially executed by another thread. A
* Runnable, however, does not return a result and cannot
* throw a checked exception.
*
* 和Runnable接口很相似
* 不同的是Runnable方法里面的run方法没有返回值,而这里的call方法有返回值
*
* The { Executors} class contains utility methods to
* convert from other common forms to Callable classes.
*
* Executors中有一些把其他形式对象转换成Callable类的方法,task是可执行任务,result是希望返回的结果
* public static <T> Callable<T> callable(Runnable task,T result)
*
* @see Executor
* @since 1.5
* @author Doug Lea
* @param <V> the result type of method call
*/
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;
}
2、Callable与Runnable接口:
1)、Runnable接口定义一个可由线程完成的任务,里面有唯一一个方法:run(),不接受任何参数,也没有返回值。
2)、Callable与Runnable最大的不同就是,它里面也有一个方法:call(),也不接受任何参数,但是有返回值。如果你希望任务完成后有一个结果反馈给你的话,那这个接口就很适合你。
3、例子:
1)、Callable不能传到Thread对象中去执行,只能通过java.util.concurrent.ExecutorService类中的<T> Future<T> submit(Callable<T> task)方法去执行任务。返回值是Future对象,通过该对象的get()方法就可以得到返回值,在任务未完成之前,get()方法会一直堵塞。
-----------------------------------------------------------------------------------
/**
* Submits a value-returning task for execution and returns a Future
* representing the pending results of the task.
* 提交一个有返回值的任务去执行,并且会返回一个Future来代表这个任务的等待结果
*
* If you would like to immediately block waiting
* for a task, you can use constructions of the form
* result = exec.submit(aCallable).get();
* 如果你想立即阻塞任务的等待,可以使用以上方式 result是任务处理结果
*
* Note: The {Executors} class includes a set of methods
* that can convert some other common closure-like objects,
* for example, {java.security.PrivilegedAction} to
* {Callable} form so they can be submitted.
*
* @param task the task to submit
* 要提交的任务
* @return a Future representing pending completion of the task
* 等待的结果 Callbale是返回(可能抛出异常的任务)的结果,这个接口实现者有一个不带任何参数的call()方法
* @throws RejectedExecutionException if task cannot be scheduled
* for execution
* @throws NullPointerException if task null
*/
<T> Future<T> submit(Callable<T> task);
-----------------------------------------------------------------------------------
/**
* Waits if necessary for the computation to complete, and then
* retrieves its result.
* 如果有必要会等到计算完成,然后返回结果
* @return the computed result
* @throws CancellationException if the computation was cancelled
* @throws ExecutionException if the computation threw an
* exception
* @throws InterruptedException if the current thread was interrupted
* while waiting
*/
V get() throws InterruptedException, ExecutionException;
4、实现了Callable的任务类:
package com.sxit.test;
import java.util.concurrent.Callable;
public class CallableImpl implements Callable {
private int age;
public CallableImpl(int age){
this.age = age;
}
//具体逻辑在这里实现,并有一个返回值
public Object call() throws Exception {
if(age<0){
return "输入年龄有误";
}else if(age<20){
return "你好,年轻人";
}else if(age<40){
return "你好,中年人";
}else{
return "你好,老年人";
}
}
}
5、测试类:
package com.sxit.test;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class CallableTest {
public static void main(String[] args) throws InterruptedException, ExecutionException {
//建立一个线程池
ExecutorService exc = Executors.newFixedThreadPool(3);
//存放返回的结果
List<Future<String>> futures = new ArrayList<Future<String>>();
for(int i = -10;i<50;i+=3){
CallableImpl call = new CallableImpl(i);
//执行callable的call方法,并有返回值
Future<String> future = exc.submit(call);
futures.add(future);
}
for(Future<String> future : futures){
//这里调用get()方法会阻塞当前线程,直到得到返回结果
System.out.println(future.get());
}
}
}
6、打印信息:
输入年龄有误
输入年龄有误
输入年龄有误
输入年龄有误
你好,年轻人
你好,年轻人
你好,年轻人
你好,年轻人
你好,年轻人
你好,年轻人
你好,中年人
你好,中年人
你好,中年人
你好,中年人
你好,中年人
你好,中年人
你好,中年人
你好,老年人
你好,老年人
你好,老年人
7、小结:
1)、Callable最大的不同和作用就是有返回值