使用executor、callable以及一个Future 计算欧拉数e
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的更多相关文章
- Java线程池 / Executor / Callable / Future
为什么需要线程池? 每次都要new一个thread,开销大,性能差:不能统一管理:功能少(没有定时执行.中断等). 使用线程池的好处是,可重用,可管理. Executor 4种线程 ...
- Callable接口和Future
本篇说明的是Callable和Future,它俩很有意思的,一个产生结果,一个拿到结果. Callable接口类似于Runnable,从名字就可以看出来了,但是Runnable不会返回结 ...
- 给出两个单词word1和word2,写一个函数计算出将word1 转换为word2的最少操作次数。
问题: 给出两个单词word1和word2,写一个函数计算出将word1 转换为word2的最少操作次数. 你总共三种操作方法: 1.插入一个字符 2.删除一个字符 3.替换一个字符 格式: 输入行输 ...
- LINUX上一个命令计算PI
Linux上一个命令计算PI – 笑遍世界 http://smilejay.com/2017/11/calculate-pi-with-linux-command/ [root@d1 goEcho]# ...
- 并发编程之Callable异步,Future模式
Callable 在Java中,创建线程一般有两种方式,一种是继承Thread类,一种是实现Runnable接口.然而,这两种方式的缺点是在线程任务执行结束后,无法获取执行结果.我们一般只能采用共享变 ...
- Java Callable接口与Future接口的两种使用方式
Java Callable.Future的两种使用方式Callable+Futurepublic class Test { public static void main(String[] args) ...
- Callable接口使用以及计算斐波那契数字的数值总和
一.简单使用 Runnable是执行工作的独立任务,但是它不返回任何值.如果你希望任务完成的时能够返回一个值,那么可以实现一个Callable接口.在Java SE5中引入的Callable是一种具有 ...
- Callable抛出异常与future.get
public class ThreadPoolTest { @Test public void testException(){ try{ testExecutorServiceException() ...
- 怎么用wait、notify巧妙的设计一个Future模式?
我们知道多线程可以实现同时执行多个任务(只是看起来是同时,其实是CPU的时间片切换特别快我们没感觉而已). 现在假设一个做饭的场景,你没有厨具也没有食材.你可以去网上买一个厨具,但是这段时间,你不需要 ...
随机推荐
- 【最短路径之dijkstra(迪杰斯特拉)算法】
这一章主要介绍最短路径的算法之一,dijkstra算法. 概念 :迪杰斯特拉算法(Dijkstra)是由荷兰计算机科学家狄克斯特拉于1959 年提出的,因此又叫狄克斯特拉算法.是从一个顶点到其余各顶点 ...
- Redis原子性写入HASH结构数据并设置过期时间
Redis中提供了原子性命令SETEX或SET来写入STRING类型数据并设置Key的过期时间: > SET key value EX NX ok > SETEX key value ok ...
- [Windows无法连接到 System Event Notification Service服务]解决方案
我之前使用Windows的过程的有出现过以下问题,之前因为比较急就匆忙解决了没来得及把解决方法写下来. 正好今天有个朋友电脑也出现此问题过来找我寻求解决方法,便把解决方法写了下来. 电脑出现的问题,如 ...
- 洛谷P1033 自由落体 题解
题目链接:https://www.luogu.org/problemnew/show/P1033 呵呵,真的学好物理比较重要,前些年卡在这题上的我今天终于会做了,可恶的自由落体(也许是我太弱了吧 ) ...
- 小白开学Asp.Net Core《二》
小白开学Asp.Net Core<二> ——数据仓储层(Repositroy) 一.历史现象 在后端开发中,数据库操作是最频繁的,每一个开发人员都会接触,甚至不少开发人员每天的工作就是与数 ...
- 从后端到前端之Vue(四)小试牛刀——真实项目的应用(树、tab、数据列表和分页)
学以致用嘛,学了这么多,在真实项目里面怎么应用呢?带着问题去学习才是最快的学习方式.还是以前的那个项目,前后端分离,现在把前端换成vue的,暂时采用脚本化的方式,然后在尝试工程化的方式. 现在先实现功 ...
- 用maven工具管理web项目的错误记录:org.springframework.beans.factory.xml.XmlBeanDefinitionStoreException
运行异常报告日志: 严重: Context initialization failedorg.springframework.beans.factory.xml.XmlBeanDefinitionSt ...
- spring与actionMQ整合
出处:http://www.cnblogs.com/leiOOlei/p/5075402.html 一.配置部分 ActiveMQ的安装这就不说了,很简单, 这个例子采用maven构建,首先看一下po ...
- Vue事件修饰符详解
整体学习Vue时看到Vue文档中有事件修饰符的描述,但是看了之后并没有理解是什么意思,于是查阅了资料,现在记录下来与大家分享 先给大家画一个示意图理解一下冒泡和捕获 (1) .stop修饰符 请看如下 ...
- Java 添加、验证PDF 数字签名
在设置文档内容保护的方法中,除了对文档加密.添加水印外,应用数字签名也是一种有效防伪手段.数字签名的文件比较容易验证,并且具有较高的权威性和可信度.在PDF文档中,有可直接添加或验证数字签名的功能方法 ...