多线程有两种实现方式:

一种是实现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. 第二百六十九天 how can I 坚持

    什么是明事理,搞不懂啊,好烦. 有点像我妈. 为什么突然就想买房了呢,为什么?年龄到了,考虑的东西就不一样了. 哎,不要想太多,睡觉.

  2. homework09-虐心的现程设终于要告一段落了

    V3.0版本今天凌晨出炉 添加了随机生成 添加了文件打开 完全按照老师的要求搞定了 V2.0版本更新 添加了中间数组变量显示 这次作业写了整整一天,把以前能用的代码都改了一个遍 最后变成了网页版的小程 ...

  3. Light oj 1197 - Help Hanzo (素数筛技巧)

    题目链接:http://lightoj.com/volume_showproblem.php?problem=1197 给你a和b求a到b之间的素数个数. 先在小区间素数筛,大区间就用类似素数筛的想法 ...

  4. C#学习笔记(十二):正则表达式

    Regex 正则表达式的类,我们可以通过该类来使用正则表达式. 比如下面我们使用Regex来判断输入的字符串是否符合指定的格式: using System; using System.Text.Reg ...

  5. MVC神韵---你想在哪解脱!(十)

    增加追加数据的方法和视图 现在我们将要在数据库中追加并保存一些数据.我们将要创建一个表单以及一些表单输入控件,用来输入数据信息.当用户提交表单时将把这些用户输入的信息保存在数据库中.我们可以通过在浏览 ...

  6. Visifire的一些使用心得

    1.如何让图表的Y轴不从0开始显示:有时一系列的数据差别很小,如果从0开始显示,在Y轴上,会一堆数据都堆在某一个区间.例如期货的蜡烛图.将ViewportRangeEnabled设为true即可解决此 ...

  7. AngularJS~集成的ajax和服务的注入

    AngularJS很美,以至于迷倒了不少年青人和我这位大叔,它的美不仅仅是在写法上,而且在设计方法上都进乎于完美,用什么服务就注入什么服务,这样方法本来就很直观,程序员感觉直观了,程序在运行起来也按需 ...

  8. .NET通用权限系统快速开发框架

    DEMO下载地址: http://download.csdn.net/detail/shecixiong/5372895 一.开发技术:B/S(.NET C# ) 1.Windows XP以上 (支援 ...

  9. DataGridView单元格合并

    本文章转载:http://www.cnblogs.com/xiaofengfeng/p/3382094.html 图: 代码就是如此简单 文件下载:DataGridView单元格合并源码 也可以参考: ...

  10. 搜狐cache文件夹设置

    比如说本来sohucache放在E盘,你想改到D盘.第一步:在运行中打开regedit,在弹出的HKEY_CURRENT_USER选中Software第二步:再选中SOHU再选中SoHuVA再选中Ca ...