多线程有两种实现方式:

一种是实现Runnable接口,另一种是继承Thread类,这两种方式都有缺点,run方法没有返回值,不能抛出异常(这两个缺点归根到底是Runable接口的缺陷,Thread也是实现了Runnable接口),如果需要知道一个线程的运行结果就需要用户自行设计,线程类自身也不能提供返回值和异常.

但是从JDK1.5之后引入了一个新的接口Callable,它类似于Runnable接口,实现它就可以实现多线程任务,Callable接口的定义如下:

public interface Callable<V> {

    V call() throws Exception;
}

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

 import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit; public class Client {
public static void main(String[] args) throws Exception {
//生成一个单线程的异步执行器
ExecutorService es = Executors.newSingleThreadExecutor();
//线程执行后的期望值
Future<Integer> future = es.submit(new TaxCalculator(100));
while(!future.isDone()){
//还没有运算完成,等待10毫秒
TimeUnit.MILLISECONDS.sleep(200);
//输出进度符号
System.out.print("#");
}
System.out.println("\n计算完成,税金是:"+ future.get() + " 元");
//关闭异步执行器
es.shutdown();
}
} //税款计算器
class TaxCalculator implements Callable<Integer> {
//本金
private int seedMoney;
//接收主线程提供的参数
public TaxCalculator(int _seedMoney) {
seedMoney = _seedMoney;
}
@Override
public Integer call() throws Exception {
//复杂计算,运行一次需要10秒
TimeUnit.MILLISECONDS.sleep(10000);
return seedMoney /10;
}
}

这里模拟了一个复杂运算,这个运算可能要花费10秒钟的时间,此时不能让用户一直等着,需要给 用户输出点什么,让用户知道系统还在运行,这也是友好性的体现,用户输入既有输出,若耗时较长,则显示进度.

如果我们直接计算,就只有一个main线程,是不可能有友好提示的,如果税金不计算完毕,也不会执行后续动作,所以此时最好的方法就是重启一个线程来运算.让main线程做进度提示.

改段代码中,Executors是一个静态工具类,提供了异步执行器的创建能力,如单线程执行器newSingleThreadExecutor,固定线程数量的执行器newFixedThreadPool等,一般它是异步计算的入口类.

Future关注的是线程执行后的结果.比如有没有运行完毕,执行结果是多少等.此段代码的运行结果如下:

###################################################
计算完成,税金是:10 元

"#"会依次递增,标识系统正在计算.

此类异步运算的好处是:

1.尽可能多的占用系统资源.提供快速运算.

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

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

[改善Java代码]异步运算考虑使用Callable接口的更多相关文章

  1. [改善Java代码]集合运算时使用更优雅的方式

    在初中代数中,我们经常会求两个集合的并集.交集.差集等,在Java中也存在着此 类运算,那如何实现呢? 一提到此类集合操作,大部分的实现者都会说:对两个集合进行遍历,即可求出结果.是的,遍历可以实现并 ...

  2. Java多线程带返回值的Callable接口

    Java多线程带返回值的Callable接口 在面试的时候,有时候是不是会遇到面试会问你,Java中实现多线程的方式有几种?你知道吗?你知道Java中有可以返回值的线程吗?在具体的用法你知道吗?如果两 ...

  3. [改善Java代码]优先选择线程池

    在Java1.5之前,实现多线程编程比较麻烦,需要自己启动线程,并关注同步资源,防止线程死锁等问题,在1.5版本之后引入了并行计算框架,大大简化了多线程开发. 我们知道线程有5个状态:新建状态(New ...

  4. [改善Java代码]易变业务使用脚本语言编写

    建议16: 易变业务使用脚本语言编写 Java世界一直在遭受着异种语言的入侵,比如PHP.Ruby.Groovy.JavaScript等,这些“入侵者”都有一个共同特征:全是同一类语言—脚本语言,它们 ...

  5. [改善Java代码]不同的列表选择不同的遍历方法

    一.场景: 我们来看一个场景,统计一个省的各科高考科目考试的平均分. 当然使用数据库中的一个SQL语句就能求出平均值,不过这个不再我们的考虑之列,这里只考虑使用纯Java的方式来解决.(由于我的机器配 ...

  6. [改善Java代码]不要让类型默默转换

    建议23:不要让类型默默转换 public class Client { // 光速是30万公里/秒,常量 public static final int LIGHT_SPEED = 30 * 100 ...

  7. java代码(14) --Java8函数式接口

    Java8函数式接口 之前有关JDK8的Lambda表达式 Java代码(1)--Java8 Lambda 函数式接口可以理解就是为Lambda服务的,它们组合在一起可以让你的代码看去更加简洁 一.概 ...

  8. [改善Java代码]减少HashMap中元素的数量

    在系统开发中我们经常会使用HashMap作为数据集容器,或者是用缓冲池来处理,一般很稳定,但偶尔也会出现内存溢出的问题(OutOfMemory错误),而且这经常是与HashMap有关的.而且这经常是与 ...

  9. [改善Java代码]适时选择不同的线程池来实现

    Java的线程池实现从最根本上来说只有两个:ThreadPoolExecutor类和ScheduledThreadPoolExecutor类,这两个类还是父子关系,但是Java为了简化并行计算,还提供 ...

随机推荐

  1. 最大连续子数组问题-homework-01

    1)先写我的 github 的介绍: github 的域名:http://www.github.com/zhuifeng1022 登入 github 大概是下面的视图: 按照助教的方法:我已经建好了代 ...

  2. work7

    uno. 理解C++变量的作用域和生命周期 没有要求讲解我就简单注释了一下~ #include <iostream>int main(){ for (int i=0;i<10;i++ ...

  3. POJ 1308 Is It A Tree? (并查集)

    Is It A Tree? 题目链接: http://acm.hust.edu.cn/vjudge/contest/123393#problem/M Description A tree is a w ...

  4. 经典代码-C宏 #转字符串【瓦特芯 笔记】

    在调试C语言程序时,有时需要打印宏的名字.可以通过定义宏,宏名字的数组来获得. 例如: #include <stdio.h> #define MACRO_STR(x) {x, #x} ty ...

  5. HDU 2045 不容易系列之(3)—— LELE的RPG难题 (递推)

    题意:略. 析:首先是假设前n-2个已经放好了,那么放第 n 个时,先考虑一下第 n-1 放的是什么,那么有两种情况. 如果n-1放的是和第1个一样的,那么第 n 个就可以在n-2的基础上放2个,也就 ...

  6. hibernate一对多关系配置

    一.     表信息 公司表 cId cName cAdress Null Null Null 表t_company 员工表 sId sName sAge cId Null Null Null Nul ...

  7. Egret项目Typescript的编译报错

    今天编译项目,出现了一个奇怪的报错,如下: E:\engine\egret-core-3.1.2\tools\lib\typescript\tsclark.js:41531 1> if (fil ...

  8. IIS6的SSL配置,如何配置SSL到登陆页,如何将SSL证书设置成受信任的证书

    一. 申请证书1. 到受信任的机构申请 略 2. 到自建的证书服务器申请 a. 安装证书服务 通过控制面板中的“添加/删除程序”,选择“添加/删除Windows组件”.在Windows组件向导中找到“ ...

  9. IoC/DI

    From:http://jinnianshilongnian.iteye.com/blog/1471944 我对IoC/DI的理解 博客分类: spring杂谈 IoCDI  IoC IoC: Inv ...

  10. Python3爬取中文网址

    本以为Python3的中文兼容性无比友好,结果还是会有一点问题的. 解决方案如下,就以爬取我自己的一个网页极简翻译为例 #coding:utf8 import urllib.request impor ...