我们在执行java多线程并发程序时有时候会碰到执行特别慢的场景,小伙伴们知道是什么原因导致的吗?它要怎么解决呢?下面小编就为你讲讲。

前提:在某地需要开发一个应用系统,此系统主要功能是能够让一些中小型企业填写企业资质信息,然后通过给定的公式,统计这一系列的信息,再以得分的形式展示给上头。当前总共有着1300家企业填报。因为得分是需要实时显示的,因此统计功能会慢到一定程度。

具体代码流程:

a.首先查出1300企业信息

b.循环遍历1300家企业的所有信息,并计算每家企业的具体得分。每家预计时间为0.3秒。合计390秒。所以页面请求超时

c.导出(jxl或jar)

给出解决方案:

因为是处理业务的,所以我们需要能有返回值的线程。因此会使用:Callable

实现

1、调用线程代码List > list = (List > ) map.get("rows");

int taskSize = 20;

// 创建一个线程池

ExecutorService pool = Executors.newFixedThreadPool(taskSize);

// 创建多个有返回值的任务

List  listFuture = new ArrayList  ();

for (int i = 0; i

{

System.out.println("我启用多线程啦啦啦");

int evgCount = list.size() / taskSize;

Callable c = new MyCallable(list.subList(evgCount * i, evgCount * (i + 1)), session, staticFlag

, declareService, declareMasterService, enterpriseQueryService);

// 执行任务并获取Future对象

Future f = pool.submit(c);

listFuture.add(f);

}

pool.shutdown();

// 获取所有并发任务的运行结果

List > listResult = new ArrayList > ();

for (Future f: listFuture)

{

List > listModel = new ArrayList > ();

try

{

listModel = (List > ) f.get();

}

catch (InterruptedException e)

{

e.printStackTrace();

}

catch (ExecutionException e)

{

e.printStackTrace();

}

listResult.addAll(listModel);

}

map.put("rows", listResult);

2、线程代码package usi.jszx.controller;

import java.util.List;

import java.util.Map;

import java.util.concurrent.Callable;

import javax.servlet.http.HttpSession;

import org.apache.commons.lang3.StringUtils;

import usi.jszx.entity.ScoreMain;

import usi.jszx.service.DeclareMasterService;

import usi.jszx.service.DeclareService;

import usi.jszx.service.EnterpriseQueryService;

import usi.sys.dto.AuthInfo;

import usi.sys.util.ConstantUtil;

class MyCallable implements Callable

{

//-----------------以下为线程调用的方法----------------

private List

, Object >> list;

private HttpSession session;

private String staticFlag;

private DeclareService declareService;

private DeclareMasterService declareMasterService;

private EnterpriseQueryService enterpriseQueryService;

public MyCallable(List > list, HttpSession session, String staticFlag

, DeclareService declareService, DeclareMasterService declareMasterService, EnterpriseQueryService enterpriseQueryService)

{

this.list = list;

this.session = session;

this.staticFlag = staticFlag;

this.declareService = declareService;

this.declareMasterService = declareMasterService;

this.enterpriseQueryService = enterpriseQueryService;

}

@Override

public Object call() throws Exception

{

AuthInfo info = (AuthInfo) session.getAttribute(ConstantUtil.AUTH_INFO);

for (int i = 0; i

{

Map  maplist = list.get(i);

String mainId = maplist.get("ID") + "";

this.gradeMaster(session, mainId, maplist.get("orgId") + "", declareMasterService, enterpriseQueryService);

List > listscore = declareMasterService.queryScoreMain(maplist.get("ID") + "", info.getRightType(), "report");

// declareMasterService.queryScoreMain(mainId,info.getRightType(),isreport);

int isdouble = 1;

if (listscore.size() > 30)

{

maplist.put("SOCRETOTAL", listscore.get(46)

.get("SCORE"));

isdouble = 2;

}

else if (listscore.size() > 22)

{

maplist.put("SOCRETOTAL", listscore.get(23)

.get("SCORE"));

}

if ("3".equals(staticFlag))

{

for (int j = 0; j

{

if (j

{

maplist.put("VALUE0" + (j + 1), listscore.get(j * isdouble)

.get("SHOW_VALUE"));

}

else

{

maplist.put("VALUE" + (j + 1), listscore.get(j * isdouble)

.get("SHOW_VALUE"));

}

}

}

//地市展示

String COUNTYID = maplist.get("COUNTYID") + "";

if ("340826".equals(COUNTYID) || "341822".equals(COUNTYID))

{

maplist.put("CITYNAME", maplist.get("COUNTYNAME") + "");

}

//企业类型

String DECLARE_EVALUATE = maplist.get("DECLARE_EVALUATE") + "";

if ("1".equals(DECLARE_EVALUATE))

{

maplist.put("DECLARE_EVALUATE_NAME", "申报");

}

else

{

maplist.put("DECLARE_EVALUATE_NAME", "评价");

}

//审核状态

String SHSTATUS = maplist.get("SHSTATUS") + "";

if ("9".equals(SHSTATUS))

{

maplist.put("STRSHSTATUS", "草稿");

}

else if ("0".equals(SHSTATUS))

{

maplist.put("STRSHSTATUS", "企业提交");

}

else if ("1".equals(SHSTATUS))

{

maplist.put("STRSHSTATUS", "市审核通过");

}

else if ("2".equals(SHSTATUS))

{

maplist.put("STRSHSTATUS", "市审核不通过");

}

else if ("3".equals(SHSTATUS))

{

maplist.put("STRSHSTATUS", "省审核通过");

}

else if ("4".equals(SHSTATUS))

{

maplist.put("STRSHSTATUS", "省审核不通过");

}

else if ("5".equals(SHSTATUS))

{

maplist.put("STRSHSTATUS", "省级审核中");

}

else if ("6".equals(SHSTATUS))

{

maplist.put("STRSHSTATUS", "退回企业修改");

}

else if ("7".equals(SHSTATUS))

{

maplist.put("STRSHSTATUS", "市级审核中");

}

else if ("11".equals(SHSTATUS))

{

maplist.put("STRSHSTATUS", "修改为申报");

}

else if ("12".equals(SHSTATUS))

{

maplist.put("STRSHSTATUS", "修改为评价");

}

if ("1".equals(staticFlag))

{

//添加修改意见

List > listDetail = declareService.queryAuditLog(mainId);

if (listDetail.size() > 0)

{

String AUDIT_OPINION = listDetail.get(0)

.get("AUDIT_OPINION") + "";

if (!StringUtils.isEmpty(AUDIT_OPINION) && !"null".equals(AUDIT_OPINION))

{

maplist.put("AUDIT_OPINION", AUDIT_OPINION);

}

else

{

maplist.put("AUDIT_OPINION", "");

}

}

//是否更名 曾用名

String ORGNAME = maplist.get("ORGNAME") + "";

String PJNAME = maplist.get("PJNAME") + "";

if (StringUtils.isEmpty(PJNAME) || "null".equals(PJNAME) ||

PJNAME.equals(ORGNAME))

{

maplist.put("ISGENGMING", "否");

maplist.put("PJNAME_E", "");

}

else

{

maplist.put("ISGENGMING", "是");

maplist.put("PJNAME_E", PJNAME);

}

}

else if ("2".equals(staticFlag))

{}

}

return list;

}

public float gradeMaster(HttpSession session, String mainId, String orgId

, DeclareMasterService declareMasterService, EnterpriseQueryService enterpriseQueryService)

{

AuthInfo info = (AuthInfo) session.getAttribute(ConstantUtil.AUTH_INFO);

String rightType = info.getRightType();

declareMasterService.deleteScoreMain(mainId);

float[] resultFirst = new float[100];

/*

* 先查询所有 附表列表

* 查看得分的地方,是直接查找主表数据的

*

* 既然审核了,主表数据肯定存起来了

* */

List > listDetail = declareMasterService.queryTaskDetail(mainId);

if ("2".equals(rightType) || "3".equals(rightType))

{

//将String 转为 float

for (int i = 0; i

{

Map  map = listDetail.get(i);

if (StringUtils.isEmpty(map.get("DECLARE_CITY_VALUE") + "") ||

"null".equals(map.get("DECLARE_CITY_VALUE") + ""))

{

resultFirst[i] = 0 f;

}

else

{

resultFirst[i] = float.parsefloat(map.get("DECLARE_CITY_VALUE") + "");

}

}

}

else

{

//将String 转为 float

for (int i = 0; i

{

Map  map = listDetail.get(i);

if (StringUtils.isEmpty(map.get("DECLARE_PROVINCE_VALUE") + "") ||

"null".equals(map.get("DECLARE_PROVINCE_VALUE") + ""))

{

resultFirst[i] = 0 f;

}

else

{

resultFirst[i] = float.parsefloat(map.get("DECLARE_PROVINCE_VALUE") + "");

}

}

}

Map  enterprise = enterpriseQueryService.getInfoByOrgId(orgId)

.get(0);

//根据 湖南省企业技术中心评价指标计算公式 进行算值 下一步算分

float ratio1 = 0 f;

float ratio2 = 0 f;

float ratio3 = 0 f;

try

{

ratio1 = float.parsefloat(enterprise.get("RATIO1") + "");

ratio2 = float.parsefloat(enterprise.get("RATIO2") + "");

ratio3 = float.parsefloat(enterprise.get("RATIO3") + "");

}

catch (Exception e)

{}

Map  map = DeclareController.getValue(resultFirst, ratio1, ratio2, ratio3);

float[] resultValue = (float[]) map.get("resultValue");

float[] resultScoreValue = (float[]) map.get("resultScoreValue");

float[] resultScore = DeclareController.getScore(resultScoreValue);

float scoreTotal = 0 f;

List > listScore = declareMasterService.queryScoreDic();

for (int i = 0; i

{

ScoreMain scoreMain = new ScoreMain();

scoreMain.setMainId(mainId);

scoreMain.setScoreName(listScore.get(i)

.get("SCORE_NAME") + "");

scoreMain.setScoreUnit(listScore.get(i)

.get("SCORE_UNIT") + "");

scoreMain.setScoreWeight(listScore.get(i)

.get("SCORE_WEIGHT") + "");

scoreMain.setDisOrder(listScore.get(i)

.get("DIS_ORDER") + "");

scoreMain.setShowValue(resultValue[i] + "");

scoreMain.setScoreValue(resultScoreValue[i] + "");

scoreMain.setScore(resultScore[i] + "");

declareMasterService.inserScoreMain(scoreMain);

scoreTotal += resultScore[i];

}

return scoreTotal;

}

}

PS:可以看到最后从390秒提速致40秒,提升巨大

以上就是整篇文章的所有内容,相信对多线程大家都已经非常了解了吧,还想了解更多相关java常见问题及解决方法的话就快关注我们网站吧。

推荐阅读:

java 多线程 变慢_java多线程并发程序执行慢有什么原因?该怎么解决?相关推荐

  1. Java Web开发中,自定义过滤器被执行两次的原因分析及解决办法

    本文出处:http://blog.csdn.net/chaijunkun/article/details/7646338,转载请注明.由于本人不定期会整理相关博文,会对相应内容作出完善.因此强烈建议在 ...

  2. Fork and Join: Java也可以轻松地编写并发程序 原文地址 作者:Julien Ponge 译者:iDestiny 资源下载: Java SE 7 Sample Code(Zi

    Fork and Join: Java也可以轻松地编写并发程序 原文地址   作者:Julien Ponge 译者:iDestiny 资源下载: Java SE 7 Sample Code(Zip) ...

  3. 程序执行报错Missing Connection or ConnectionString 解决方法

    程序执行报错Missing Connection or ConnectionString 解决方法 参考文章: (1)程序执行报错Missing Connection or ConnectionStr ...

  4. java 多线程变量可见性_Java多线程:易变变量,事前关联和内存一致性

    java 多线程变量可见性 什么是volatile变量? volatile是Java中的关键字. 您不能将其用作变量或方法名称. 期. 我们什么时候应该使用它? 哈哈,对不起,没办法. 当我们在多线程 ...

  5. java进程与线程_Java多线程笔记(零):进程、线程与通用概念

    前言 不积跬步,无以至千里:不积小流,无以成江海.在学习Java多线程相关的知识前,我们首先需要去了解一点操作系统的进程.线程以及相关的基础概念. 进程 通常,我们把一个程序的执行称为一个进程.反过来 ...

  6. java main是多线程的吗_Java多线程之线程及其常用方法

    创建线程和常用方法 进程与线程的概念进程 进程是程序执行时的一个实例.程序运行时系统就会创建一个进程,并为它分配资源,然后把该进程放入进程就绪队列,进程调度器选中它的时候就会为它分配CPU时间,程序开 ...

  7. java线程知识梳理_Java多线程——多线程相关知识的逻辑关系梳理

    1 学习多线程知识的根本目标 多线程知识的根本目标是:设计稳健的并发程序. 当然,本文无法回答这个实践性很强的问题(这与具体的业务相关,涉及到具体的策略),本文主要阐述相关知识之间的关系,希望初学者不 ...

  8. java多线程 cpu分配_java多线程总结(转载)

    Java 多线程编程总结 --------------------------------------------------------------------------------------- ...

  9. java 线程 异常中断_java多线程并发之旅-19-InterruptedException 中断异常处理及中断机制...

    引言 如果对 Java 中断没有一个全面的了解,可能会误以为被中断的线程将立马退出运行,但事实并非如此. 中断机制是如何工作的?捕获或检测到中断后,是抛出 InterruptedException 还 ...

最新文章

  1. 7个方面读懂6月的5G标准
  2. 【转】Android Recovery模式
  3. 河南大学明德计划2020计算机学院,关于选拔2020级物理学“明德计划”实验班学生的通知...
  4. OpenCV推断onnx格式目标检测模型(SSD)(附完整代码)
  5. C# 对WinForm应用程序的App.config的使用及加密
  6. Hibernate-HQL
  7. GCJ 2008 Round 1A Minimum Scalar Product( 水 )
  8. 最短路弗洛伊德(Floyd)算法加保存路径
  9. java golang速度_golang思考之运行速度
  10. WebStorm 代码文字发虚模糊 - 解决篇
  11. WinXP升级IE6至IE8以及WIN7下IE8升级至IE11
  12. 【机器学习原理】SVM支持向量机分类算法
  13. 2019深圳罗湖民办小学有哪些?查查吧深圳学区地图
  14. 如何读计算机领域的论文,计算机领域学术论文分类
  15. treap【来自蒟蒻的整理】
  16. linux shell 脚本手动执行没问题,但在任务计划中执行有问题
  17. python全栈开发中级班全程笔记(第三模块、第一章(多态、封装、反射、内置方法、元类、作业))...
  18. 选择system bus还是session bus?
  19. K8S kube-proxy iptables 原理分析
  20. Oracle的逻辑读和物理读

热门文章

  1. 实习期内容:编写一个QGIS的C++插件,用于完成WMTS的切片功能(要在vs上写出功能,然后把功能和QT的界面连接在一起,最后转到qgis上当插件)
  2. 李宏毅ML作业笔记1: 预测PM2.5(kaggle预测与报告题目)
  3. Linux 高效使用 alias 总结
  4. java-php-python-ssm犬物语宠物店体验购物系统计算机毕业设计
  5. day01-乐优商城项目搭建
  6. layui数据表格table在选项卡tabs中分页条不显示的解决
  7. 基于Python实现的图的同构算法
  8. C++ : switch:switch string的两种用法
  9. 从股市狂跌谈集体无意识
  10. 字符串方法——截取字符串