异步运算考虑使用Callable接口 有返回值的线程

原创 2015年11月17日 17:29:58

多线程应用有两种实现方式,一种是实现Runnable接口,另一种是继承Thread类,这 两个方式都有缺点:run方法没有返回值,不能抛出异常(这两个缺点归根到底是Runable 接口的缺陷,Thread也是实现了 Runnable接口),如果需要知道一个线程的运行结果就需要用 户自行设计,线程类自身也不能提供返回值和异常。但是从Java 1.5开始引入了一个新的接口 Callable,它类似于Runable接口,实现它就可以实现多线程任务,Callable的接口定义如下:

public interface Callable<V> {

  //具有返回值,并可抛出异常

    V call() throws Exception;

}

实现Callable接口的类,只是表明它是一个可调用的任务,并不表示它具有多线程运算能力,还是需要执行器来执行的。我们先编写一个任务类,代码如下:

//税款计算器
class TaxCalculator implements Callable<Integer>{
	//本金
 private int seedMoney;
//接收主线程提供的参数
 public TaxCalculator(int _seedMoney) {
	// TODO Auto-generated constructor stub
     seedMoney=_seedMoney;
 }
	
	@Override
	public Integer call() throws Exception {
		// TODO Auto-generated method stub
		//复杂计算,运行一次需要10秒 
		TimeUnit.MILLISECONDS.sleep(10000);
		return seedMoney/10;
	}
	
}

这里模拟了一个复杂运算:税款计算器,该运算可能要花费10秒钟的时间,此时不能 让用户一直等着吧,需要给用户输出点什么,让用户知道系统还在运行,这也是系统友好性的体现:用户输入即有输出,若耗时较长,则显示运算进度。如果我们直接计算,就只有一 个main线程,是不可能有友好提示的,如果税金不计算完毕,也不会执行后续动作,所以

此时最好的办法就是重启一个线程来运算,让main线程做进度提示,代码如下:

public class TestCallable {
  public static void main(String[] args) throws Exception {
    //生成一个单线程的异步执行器
    ExecutorService es=Executors.newSingleThreadExecutor();
    //线程执行后的期望值
    Future<Integer> future=es.submit(new TaxCalculator(100));
    while(!future.isDone()){
        //还没有运算完成,等待200毫秒
        TimeUnit.MICROSECONDS.sleep(200);
        //输出进度符号
        System.out.println("#");
    }
    System.out.println("\n计算完成,税金是:"+future.get()+"元");
    es.shutdown();
}
}

在该段代码中,Executors是一个静态工具类,提供了异步执行器的创建能力,如单线程 执行器newSingleThreadExecutor、固定线程数量的执行器newFixedThreadPool等,一般它 是异步计算的入口类。Future关注的是线程执行后的结果,比如有没有运行完毕,执行结果 是多少等。此段代码的运行结果如下所示:

##################################################

计算完成,税金是10元

执行时,“#”会依次递增,表示系统正在运算,为用户提供了运算进度。此类异步计算的好处是:

□尽可能多地占用系统资源,提供快速运算。

□可以监控线程执行的情况,比如是否执行完毕、是否有返回值、是否有异常等。

□可以为用户提供更好的支持,比如例子中的运算进度等。

版权声明:本文为博主原创文章,未经博主允许不得转载。 举报

相关文章推荐

异步接收子线程的返回值

上次在做版本升级时遇到一个这样的需求:服务器需要向客户端发送版本文件,采用的是TCP + pthread来实现,其中,发送结果需要返回给主线程。这让我想起了子进程的操作退出后会给主进程发送一个信号,而...

Callable接口的使用

Callable是一个接口,用于创建有返回值的线程。相对地,一般我们会实现Runnable接口去构造一个Thread,但是Runnable是没有返回值的。在此记录一下Callable的用法。 比如,...

精选:深入理解 Docker 内部原理及网络配置

网络绝对是任何系统的核心,对于容器而言也是如此。Docker 作为目前最火的轻量级容器技术,有很多令人称道的功能,如 Docker 的镜像管理。然而,Docker的网络一直以来都比较薄弱,所以我们有必要深入了解Docker的网络知识,以满足更高的网络需求。

接口返回值规则

技术团队工作中,接口的规则相当重要。接口可分为两部分,入参和返回值。下面就简单阐述我的相关思考:返回结果,使用json表示: {“code”:0,”thirdCode”:”“,”msg”:”[fon...

有返回值的线程

在Java5之前,线程是没有返回值的,常常为了“有”返回值,破费周折,而且代码很不好写。或者干脆绕过这道坎,走别的路了。   现在Java终于有可返回值的任务(也可以叫做线程)了。   可返回...
  • kouwoo
  • kouwoo
  • 2015-11-16 11:02
  • 1633

Callable 获取线程返回值

allable与 Future 两功能是Java在后续版本中为了适应多并法才加入的,Callable是类似于Runnable的接口,实现Callable接口的类和实现Runnable的类都是可被其他线...

java 多线程 返回值 Callable

package cn; import java.util.concurrent.*; import java.util.Date; import java.util.List; import ...

Callable 与 FutureTask:有返回值的多线程

转自  http://www.cnblogs.com/yjl49/archive/2012/09/26/2704274.html  常用的Thread类在run方法执行完之后是没有返...

Java多线程研究06-带返回值的线程定义接口Callable以及Future,FutureTask的使用

带返回值的CallableJAVA线程相关的Runnable接口中的run()方法没有提供返回值,如下:...... public void run() { ...... } ......如果...

使用Callable返回结果

自从Java平台的最开始,Runnable接口就已存在了。它允许你定义一个可由线程完成的任务。 如大多数人所已知的那样,它只提供了一个run 方法,该方法既不接受任何参数,也不返回任何值。 如果你...

用Fiddler设置断点修改接口返回值

1.Fiddler连上手机,开始抓包(手机设置代理,ip写本电脑IP,端口写8888) 2.打开Fiddler,设置断点:Rules-Automatic Breakpoints-After Resp...
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)