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
非常感谢!!!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值