当前位置: 首页 > news >正文

建设银行网站特点分析高端网站特色

建设银行网站特点分析,高端网站特色,如何盗取网站,济南手机建站公司一、项目背景 这几天要开发一个类似支付宝那种年度账单统计的功能#xff0c;就是到元旦后支付完会把用户这一年的消费情况从各个维度#xff08;我们把这一个维度称作一个指标#xff09;统计分析形成一张报告展示给用户。 这个功能实现用到了CountDownLatch。假如统计分析…       一、项目背景 这几天要开发一个类似支付宝那种年度账单统计的功能就是到元旦后支付完会把用户这一年的消费情况从各个维度我们把这一个维度称作一个指标统计分析形成一张报告展示给用户。 这个功能实现用到了CountDownLatch。假如统计分析用户的年底消费账单是10个指标。则希望用10线程并发去分别统计这10个指标等10个线程都完成计算后最后在通过另外一个线程汇总10个指标返给前端展示给用户。 二、问题描述 其中出现了这样一个问题生成第一个用户的年度账单是10个指标计算完后最后一个线程进行最后的结果统计。这没问题。但是在生成第二个用户年底账单时返给前端的是空。但是数据库里却生成了第二用户的年度账单。后面生成的所有用户年度账单都是空且数据库都有每个用户的账单。 三、错误代码示例 package com.lsl.controller;import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody;import java.util.Date; import java.util.HashMap; import java.util.Map; import java.util.concurrent.*;Controller RequestMapping(/latch) public class CountDownLatchController {//创建固定线程池最大线程数10private static ExecutorService executor Executors.newFixedThreadPool(10);//模拟并发任务数private static int taskNum 10;//计数器CountDownLatch latch new CountDownLatch(taskNum);PostMapping(value execTask, produces application/json;charsetUTF-8)ResponseBodypublic String execTask(){for (int i taskNum;i1;i--){String name thread;FutureMap submit executor.submit(new CountNumTask(latch,name, i)); // try { // Map map submit.get(); // String ThreadName map.get(name).toString(); // String total map.get(total).toString(); // System.err.println(ThreadName: ThreadName ,total total); // } catch (InterruptedException e) { // e.printStackTrace(); // } catch (ExecutionException e) { // e.printStackTrace(); // }}try {latch.await(10, TimeUnit.SECONDS);} catch (InterruptedException e) {e.printStackTrace();}//正常情况下,等10个任务执行完毕下面的主线程才输出System.out.println(主线程开始执行了.....);return success;}/*** 线程任务*/private class CountNumTask implements CallableMap{private String name;private int num;private CountDownLatch latch;public CountNumTask(CountDownLatch latch,String name,int num){this.latch latch;this.name name;this.num num;}Overridepublic Map call() throws Exception {long st new Date().getTime();Map resultMap new HashMap();String threadName name num;resultMap.put(name,threadName);int total 0;for (int i 0;inum;i){total i;}Thread.sleep(num100);//每个任务sleep不同,模拟线程耗时不一样resultMap.put(total,total);long ed new Date().getTime();System.err.println(ThreadName: threadName ,total total ,耗时 (ed-st));latch.countDown();return resultMap;}} }第一次调用截图 第二次调用截图 从上面截图可以看出10个指标线程还没有运行完主线程就先输出了。 四、原因分析 原来是CountDownLatch latch new CountDownLatch(taskNum);定义成成员变量了。这个应用定义成局部变量也就是放在方法内。 原因是spring托管的bean都是单例的第一次调用结束后latch.getCount()已经是0了然后后面的调用就不会等待前面子任务完成就开始执行主线程任务了。这就是为什么数据库里有每次的数据而没有返给前端的原因。 网上有的说法是错误他们认为是线程内的latch.countDown();没有执行应该把这个放在fianlly语句快内保证改计数器减1操作每次都能执行。 如果是这样那么计数器没有到0如果在方法内latch.await(10, TimeUnit.SECONDS);这个语句就可以看出10秒钟后主线程也会执行那么上面的10个线程如果每个任务的耗时都超过10秒才能出现主线程比子任务输出早的情况。如果采用的是latch.await();那么主线程就会被永远阻塞了因为计数器没有到0。这个前提是CountDownLatch latch new CountDownLatch(taskNum)这个定义的是局部变量。 五、正确的代码示例 package com.lsl.controller;import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody;import java.util.Date; import java.util.HashMap; import java.util.Map; import java.util.concurrent.*;Controller RequestMapping(/latch) public class CountDownLatchController {//创建固定线程池最大线程数10private static ExecutorService executor Executors.newFixedThreadPool(10);//模拟并发任务数private static int taskNum 10;PostMapping(value execTask, produces application/json;charsetUTF-8)ResponseBodypublic String execTask(){//计数器CountDownLatch latch new CountDownLatch(taskNum);for (int i taskNum;i1;i--){String name thread;FutureMap submit executor.submit(new CountNumTask(latch,name, i)); // try { // Map map submit.get(); // String ThreadName map.get(name).toString(); // String total map.get(total).toString(); // System.err.println(ThreadName: ThreadName ,total total); // } catch (InterruptedException e) { // e.printStackTrace(); // } catch (ExecutionException e) { // e.printStackTrace(); // }}try {latch.await(10, TimeUnit.SECONDS);} catch (InterruptedException e) {e.printStackTrace();}//正常情况下,等10个任务执行完毕下面的主线程才输出System.out.println(主线程开始执行了.....);return success;}/*** 线程任务*/private class CountNumTask implements CallableMap{private String name;private int num;private CountDownLatch latch;public CountNumTask(CountDownLatch latch,String name,int num){this.latch latch;this.name name;this.num num;}Overridepublic Map call() throws Exception {long st new Date().getTime();Map resultMap new HashMap();String threadName name num;resultMap.put(name,threadName);int total 0;for (int i 0;inum;i){total i;}Thread.sleep(num100);//每个任务sleep不同,模拟线程耗时不一样resultMap.put(total,total); // if (num!5)long ed new Date().getTime();System.err.println(ThreadName: threadName ,total total ,耗时 (ed-st));latch.countDown();return resultMap;}} }两次调用截图 六、其他几点细节 细节1、从代码分析thread10是第一进入进入线程的为什么确实最后进入线程的thread1先输出了呢原因从截图中我打印的耗时就能看出来就是thread10耗时最长所以最晚输出。 细节2、如果我把下图的代码放开且把计数器还定义成成员变量会有什么结果呢结果可能出乎大家意料很好玩哦 我把代码附下面 package com.lsl.controller;import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody;import java.util.Date; import java.util.HashMap; import java.util.Map; import java.util.concurrent.*;Controller RequestMapping(/latch) public class CountDownLatchController {//创建固定线程池最大线程数10private static ExecutorService executor Executors.newFixedThreadPool(10);//模拟并发任务数private static int taskNum 10;//计数器CountDownLatch latch new CountDownLatch(taskNum);PostMapping(value execTask, produces application/json;charsetUTF-8)ResponseBodypublic String execTask(){for (int i taskNum;i1;i--){String name thread;FutureMap submit executor.submit(new CountNumTask(latch,name, i));try {Map map submit.get();String ThreadName map.get(name).toString();String total map.get(total).toString();System.err.println(ThreadName: ThreadName ,total total);} catch (InterruptedException e) {e.printStackTrace();} catch (ExecutionException e) {e.printStackTrace();}}try {latch.await(10, TimeUnit.SECONDS);} catch (InterruptedException e) {e.printStackTrace();}//正常情况下,等10个任务执行完毕下面的主线程才输出System.out.println(主线程开始执行了.....);return success;}/*** 线程任务*/private class CountNumTask implements CallableMap{private String name;private int num;private CountDownLatch latch;public CountNumTask(CountDownLatch latch,String name,int num){this.latch latch;this.name name;this.num num;}Overridepublic Map call() throws Exception {long st new Date().getTime();Map resultMap new HashMap();String threadName name num;resultMap.put(name,threadName);int total 0;for (int i 0;inum;i){total i;}Thread.sleep(num100);//每个任务sleep不同,模拟线程耗时不一样resultMap.put(total,total); // if (num!5)long ed new Date().getTime();System.err.println(ThreadName: threadName ,total total ,耗时 (ed-st));latch.countDown();return resultMap;}} }运行截图如下图 从上面截图是不是发现了很奇怪啊计数器定义成了成员变量第二次调用为什么主线程是等前面10子任务都完成了才输出呢而且子任务的输出顺序也对了是从thread10到thread1依次输出虽然thread10耗时最长也是第一个输出了!!! 出现上述2个反常大家知道什么原因吗欢迎在评论区留言 具体原因我会过几天在公布吧 【因为submit.get()方法会依次获取线程的结果。而不是先获取到最新执行完的线程结果】 细节3、如果把线程内的latch.countDown()位置调整到最开始位置会出现什么结果呢 如下图 运行结果截图如下 从细节3的现象可以看出latch.countDown()位置放到线程任务的最后面这个很重要。因为在latch.wait实时读取计数器的数值是否到0了一旦到0了后面的主线程就里面执行了。这就和另外的CyclicBarrier(循环栅栏)有所区别了。 细节4latch.countDown()一定要放在线程内所有任务完成之后。
http://www.zqtcl.cn/news/397568/

相关文章:

  • 无锡大型网站建设房地产景区网站建设方案
  • 自学网站建设工资公众号怎么开通直播功能
  • 网站建设上市公司wordpress park主题
  • 百度网站建设一年多少钱奇艺广州网站建设 熊掌号
  • 建设网站怎么收费标准网站和自媒体都可以做
  • 网站自己怎么做无锡常规网络营销是什么
  • 活泼风格的网站crm免费客户管理系统
  • 网站系统发生错误百度seo灰色词排名代发
  • 免费做名片儿的网站wordpress grace6
  • 有关网站开发的创意四川工程造价信息网官网
  • 网站目录结构北京注册公司地址可以是住宅吗
  • 龙信建设集团网站傻瓜式建站软件下载
  • 在360做网站和百度做网站的区别什么是网站地址
  • 营销型的物流网站模板下载长江设计公司
  • 网站程序制作购买网站域名
  • 网站建设中html下载如何用社交网站开发客户
  • 开设购物网站的方案政务公开和网站建设情况
  • 一台云服务器做多个网站营销型网站的建设重点是什么
  • 泉港网站建设推广服务公司电子商务好就业吗
  • 自己做网站开发如何找客户wordpress 显示 子分类
  • 腾讯邮箱网页版登录宿迁seo公司
  • 网站建设找盖亚科技WordPress 百度 主动
  • 中国最受欢迎的网站杭州做电商网站
  • 百度招聘 网站开发全网营销实战培训
  • 备案网站内容说明广州哪个区封了
  • 大足建网站的软件开发者模式怎么打开
  • 中国有什么网站做跨境零售农商1号的网站建设费
  • 用宝塔给远程网站做备份购买一个网站需要多少钱
  • 百度蜘蛛不爬取网站做汽车新闻哪个网站好
  • 三维建设项目管理网站免费下载网站模板