Java多线程之Callable接口的实现
一、基本理论
(1)Java 5.0 在 java.util.concurrent 提供了一个新的创建执行线程的方式:Callable 接口
(2)Callable 接口类似于 Runnable,两者都是为那些其实例可能被另一个线程执行的类设计的。但是 Runnable 不会返回结果,并且无法抛出经过检查的异常。如果我们希望任务完成之后有返回值,可以实现Callable接口。在JavaSE5中引入的Callable是一个具有类型参数的范型,他的类型参数方法表示为方法call()而不是run()中返回的值,并且必须使用ExecutorService.submint()方法进行调用
。
(3)Callable 需要依赖FutureTask ,FutureTask 也可以用作闭锁
。
二、代码实例
1、
//实现接口Callable 参数类型是String
public class TaskWithResult implements Callable<String> {
private int id;
public TaskWithResult(int id){
this.id=id;
}
@Override
public String call() throws Exception {
return "result of TaskWithResult "+id;
}
}
//java测试方法,基于junit4
@Test
public void main2() {
ExecutorService exec= Executors.newCachedThreadPool();
//Future接口后面有源码
ArrayList<Future<String>> results=new ArrayList<Future<String>>();
long start=System.currentTimeMillis();
for(int i=0;i<10;i++){
results.add(exec.submit(new TaskWithResult(i)));
}
//System.out.println("====================cost:"+(System.currentTimeMillis()-start));
int count=0;
//遍历数据
for(Future<String> fs:results){
//System.out.println("========cost:"+(System.currentTimeMillis()-start));
long start2=System.currentTimeMillis();
try{
//取数据
System.out.println(fs.get());
}catch (InterruptedException e){
System.out.print(e);
}catch (ExecutionException e){
System.out.print(e);
}finally {
exec.shutdown();
}
//System.out.println((count++)+"====================cost:"+(System.currentTimeMillis()-start2));
}
}
运行结果如下:
2、
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
/* * 一、创建执行线程的方式三:实现 Callable 接口。
相较于实现 Runnable 接口的方式,方法可以有返回值,并且可以抛出异常。
* * 二、执行 Callable 方式,需要 FutureTask 实现类的支持,用于接收运算结果。
* FutureTask 是 Future 接口的实现类
* */
public class TestCallable {
public static void main(String[] args) {
ThreadDemo td = new ThreadDemo();
//1.执行 Callable 方式,需要 FutureTask 实现类的支持,用于接收运算结果。
FutureTask<Integer> result = new FutureTask<>(td);
new Thread(result).start();
//2.接收线程运算后的结果
try {
Integer sum = result.get(); //FutureTask 可用于 闭锁 类似于CountDownLatch的作用,在所有的线程没有执行完成之后这里是不会执行的
System.out.println(sum);
System.out.println("------------------------------------");
}catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
}
class ThreadDemo implements Callable<Integer> {
@Override
public Integer call() throws Exception {
int sum = 0;
for (int i = 0; i <= 100000; i++) {
sum += i;
}
return sum;
}
}
从上面的例子可以看到: Callable 和 Future接口的区别
(1)Callable规定的方法是call(),而Runnable规定的方法是run().
(2)Callable的任务执行后可返回值,而Runnable的任务是不能返回值的。
(3)call()方法可抛出异常,而run()方法是不能抛出异常的。
(4)运行Callable任务可拿到一个Future对象,Future表示异步计算的结果。
(5)它提供了检查计算是否完成的方法,以等待计算的完成,并检索计算的结果。
(6)通过Future对象可了解任务执行情况,可取消任务的执行,还可获取任务执行的结果。
(7)Callable是类似于Runnable的接口,实现Callable接口的类和实现Runnable的类都是可被其它线程执行的任务。
三、Callable的接口源码
@FunctionalInterface
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;
}
四、Future 的接口源码
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;
}
参考自链接:https://www.jianshu.com/p/170fd03ab724
非常感谢!!!
上一篇: MicroPhp框架代码
下一篇: 给多个地址发邮件的类_PHP