package test;

import java.math.BigDecimal;
import java.math.MathContext;
import java.math.RoundingMode;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future; public class CaculateE {
final static int num=17;
public static void main(String[] args) {
// TODO Auto-generated method stub
//使用线程池防止多条人物提交而创建的线程
ExecutorService executor=Executors.newFixedThreadPool(1);
Callable<BigDecimal> callable=new Callable<BigDecimal>() { @Override
public BigDecimal call() throws Exception {
// TODO Auto-generated method stub
//舍位模式,四舍五入,100为e的精度上限
MathContext mc=new MathContext(100,RoundingMode.HALF_UP);
BigDecimal result=BigDecimal.ZERO;
//e=1/0!+1/1!+1/2!+1/3!+...+...
for(int i=0;i<num;i++) {
//factory()表示阶乘的结果 new BigDecimal() 确保结果精确,防止精度丢失
BigDecimal factorial=factory(new BigDecimal(i));
System.out.println("factorial:"+factorial);
//1除以factorial的阶乘
BigDecimal res=BigDecimal.ONE.divide(factorial,mc);
System.out.println("res:"+res);
result=result.add(res);
System.out.println("result:"+result);
}
return result;
}
//不用该方法进行转换会报执行异常
private BigDecimal factory(BigDecimal n) {
// TODO Auto-generated method stub
System.err.println("n的值为:"+n);
if(n.equals(BigDecimal.ZERO)) { return BigDecimal.ONE;
}
else {
//subtract(n.subtract(BigDecimal.ONE)) 对象中的值相减
return n.multiply(factory(n.subtract(BigDecimal.ONE)));}
} }; //提交一个runable任务进行执行,同时返回一个代表此任务的Future实例
Future<BigDecimal> taskFuture =executor.submit(callable);
try {
//判断任务是否完成,模拟任务执行,未完成输出waiting,完成之后直接输出结果
while(!taskFuture.isDone())
System.out.println("waiting/");
//线程执行之后可以获取结果
//Callable接口代表一段可以调用并返回结果的代码;Future接口表示异步任务,是还没有完成的任务给出的未来结果。所以说Callable用于产生结果,Future用于获取结果。
System.out.println("taskFuture的get()方法"+taskFuture.get()); }catch(ExecutionException e){
System.err.println("哦豁,抛出执行异常了!");
}catch (InterruptedException ie) {
// TODO Auto-generated catch block
ie.printStackTrace();
System.err.println("interrupted while waiting");
}
executor.shutdown();
}
}

代码执行流程:

main()方法调用Excutors的newFixedThreadPool方法获取一个executor.之后初始化实现了Callable接口的匿名类并且将这个任务提交给executor,在返回接收一个Future的实例。

通过isDone()判断是否执行完毕,’waiting‘表示一直在执行,当执行完毕,直接通过 taskFuture.get()获取计算的结果。

阶乘求值过程(包含一个递归):

return n.multiply(factory(n.subtract(BigDecimal.ONE)));
例如:5*factory(4)
=>5*4*factory(3)
=>
5*4*3*factory(2)
=>5*4*3*2*factory(1)
=>5*4*3*2*1*factory(0)
=>120
i 0 1 2 3 4 5 6 ... 16
返回值 factor(0) 1*factory(0) 2*factory(1) 3*factory(2) 4*factory(3) 5*factory(4) 6*factory(5) ... 16*factory(15)
factorial factory(0) 1*factory(0) 2*1*factory(0) 3*2*1*factory(0) 4*3*2*factory(0) 5*4*3*2*factory(0) 6*5*4*3*2*factory(0) ... 16*15*..*2*factory(0)
factorial 1 1 2 6 12 60 120 ... 16*15*..*2*factory(0)
res 1/1 1/1+1/1 1/1+1/1+1/2 1/1+1/1+1/2+1/6 1/1+1/1+1/2+1/6+1/12 1/1+1/1+1/2+1/6+1/12+1/60 1/1+1/1+1/2+1/6+1/12+1/60+1/120 ... 1/1+...+1/16*15*..*2*1

ps:增加精度和num的值以求更长的收敛时间和更为接近的e

使用executor、callable以及一个Future 计算欧拉数e的更多相关文章

  1. Java线程池 / Executor / Callable / Future

    为什么需要线程池?   每次都要new一个thread,开销大,性能差:不能统一管理:功能少(没有定时执行.中断等).   使用线程池的好处是,可重用,可管理.   Executor     4种线程 ...

  2. Callable接口和Future

    本篇说明的是Callable和Future,它俩很有意思的,一个产生结果,一个拿到结果.        Callable接口类似于Runnable,从名字就可以看出来了,但是Runnable不会返回结 ...

  3. 给出两个单词word1和word2,写一个函数计算出将word1 转换为word2的最少操作次数。

    问题: 给出两个单词word1和word2,写一个函数计算出将word1 转换为word2的最少操作次数. 你总共三种操作方法: 1.插入一个字符 2.删除一个字符 3.替换一个字符 格式: 输入行输 ...

  4. LINUX上一个命令计算PI

    Linux上一个命令计算PI – 笑遍世界 http://smilejay.com/2017/11/calculate-pi-with-linux-command/ [root@d1 goEcho]# ...

  5. 并发编程之Callable异步,Future模式

    Callable 在Java中,创建线程一般有两种方式,一种是继承Thread类,一种是实现Runnable接口.然而,这两种方式的缺点是在线程任务执行结束后,无法获取执行结果.我们一般只能采用共享变 ...

  6. Java Callable接口与Future接口的两种使用方式

    Java Callable.Future的两种使用方式Callable+Futurepublic class Test { public static void main(String[] args) ...

  7. Callable接口使用以及计算斐波那契数字的数值总和

    一.简单使用 Runnable是执行工作的独立任务,但是它不返回任何值.如果你希望任务完成的时能够返回一个值,那么可以实现一个Callable接口.在Java SE5中引入的Callable是一种具有 ...

  8. Callable抛出异常与future.get

    public class ThreadPoolTest { @Test public void testException(){ try{ testExecutorServiceException() ...

  9. 怎么用wait、notify巧妙的设计一个Future模式?

    我们知道多线程可以实现同时执行多个任务(只是看起来是同时,其实是CPU的时间片切换特别快我们没感觉而已). 现在假设一个做饭的场景,你没有厨具也没有食材.你可以去网上买一个厨具,但是这段时间,你不需要 ...

随机推荐

  1. C# 与 JS 之间传值在 cshtml页面中

    @{ string It = "sss"; ; } @functions{ string Mod = "ajssaioi"; public string Itm ...

  2. 个人永久性免费-Excel催化剂功能第69波-专业图表库新增图表-刘万祥老师中国地图

    Excel催化剂的[专业图表库],仅提供一个工具的输出,让用户可以在制作专业图表过程中更低的门槛,更快速的完成所想要实现的图表.具体参考:第69波-打造最专业易用的商务图表库https://www.j ...

  3. [springboot] 搭建项目及单元测试

    本文纯属记录自己学习的过程以及相关使用操作,使用工具Idea2018. 1.创建项目: -- 目录结构 2.配置文件   3.pom文件 4.创建测试类并启动项目 package com.zr.dem ...

  4. SpringBoot第二十二篇:应用监控之Actuator

    作者:追梦1819 原文:https://www.cnblogs.com/yanfei1819/p/11226397.html 版权声明:本文为博主原创文章,转载请附上博文链接! 引言   很多文章都 ...

  5. 使用RabbitMQ做数据接收和处理时,自动关闭

    场景:N个客户端向MQ里发送数据:服务器上有另一个控制台程序(假设叫ServerClient)来处理这里数据(往数据库保存).方向为Client * n→MQSERVER→ServerClient 问 ...

  6. [WPF自定义控件库]自定义Expander

    1. 前言 上一篇文章介绍了使用Resizer实现Expander简单的动画效果,运行效果也还好,不过只有展开/折叠而缺少了淡入/淡出的动画(毕竟Resizer模仿Expander只是附带的功能).这 ...

  7. 数组(ArrayPool数组池、Span<T>结构)

    前言 如果需要使用相同的类型的多个对象,就可以使用集合和数组,这一节主要讲解数组,其中会重点涉及到Span<T>结构和ArrayPool数组池.我们也会先涉及到简单的数组.多维数组.锯齿数 ...

  8. httpclient 方式提供接口

    在后台写好自己的方法: 打开shiro验证,设置url访问: 提供包调用http方式连接后台获取数据: String url = getUrl(); HttpClient client = new H ...

  9. Mybatis连接查询返回类型问题

    一对一映射 public class Card { private Integer id; private String num; private Student student; //重要 publ ...

  10. DataOps系列丨数据的“资产负债表”与“现状”

    作者:DataPipeline CEO 陈诚 <跨越鸿沟>的作者Geoffrey Moore曾说“没有数据,运营企业就像一个又聋又瞎的人在高速上开车一样”.数据的价值从未像现在这样被企业重 ...