Java多线程执行处理业务时间太久解决方法代码示例

背景:在政府开发了一个应用系统,主要功能是让企业填写企业资质信息,然后通过给定的公式,统计这一系列的信息,以得分的形式展示给政府领导查看。目前有1300家企业填报。由于得分是实时显示的,所以导致统计功能很慢。

代码运行流程

1、查出1300企业信息

2、遍历1300企业信息,ji计算每家企业得分信息。每家预计时间为0.3秒。合计390秒。导致页面请求超时

3、导出(用jxl jar)

解决方案:

由于处理业务的,所以需要能有返回值的线程。用:Callable

直接上代码

1、调用线程的代码

List<Map<String,Object>> list = (List<Map<String, Object>>) map.get("rows");
int taskSize = 20;
// 创建一个线程池
ExecutorService pool = Executors.newFixedThreadPool(taskSize);
// 创建多个有返回值的任务
List<Future> listFuture = new ArrayList<Future>();
for (int i = 0; i < taskSize; 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<Map<String, Object>> listResult = new ArrayList<Map<String, Object>>();
for (Future f : listFuture) {
	List<Map<String, Object>> listModel = new ArrayList<Map<String, Object>>();
	try {
		listModel = (List<Map<String, Object>>) 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<Object> {
	//-----------------以下为线程调用的方法----------------
	private List<Map<String,Object>> list;
	private HttpSession session;
	private String staticFlag;
	private DeclareService declareService;
	private DeclareMasterService declareMasterService;
	private EnterpriseQueryService enterpriseQueryService;
	public MyCallable(List<Map<String,Object>> 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 < list.size(); i++) {
			Map<String,Object> maplist = list.get(i);
			String mainId= maplist.get("ID")+"";
			this.gradeMaster(session, mainId, maplist.get("orgId")+"",declareMasterService,enterpriseQueryService);
			List<Map<String,Object>> 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 < 23; j++) {
					if(j<9){
						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<Map<String, Object>> 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<Map<String,Object>> listDetail = declareMasterService.queryTaskDetail(mainId);
		if("2".equals(rightType)||"3".equals(rightType)){
			//将String 转为 float
			for (int i = 0; i < listDetail.size(); i++) {
				Map<String,Object> map = listDetail.get(i);
				if(StringUtils.isEmpty(map.get("DECLARE_CITY_VALUE")+"")
				||"null".equals(map.get("DECLARE_CITY_VALUE")+"")){
					resultFirst[i]=0f;
				} else{
					resultFirst[i] = float.parsefloat(map.get("DECLARE_CITY_VALUE")+"");
				}
			}
		} else{
			//将String 转为 float
			for (int i = 0; i < listDetail.size(); i++) {
				Map<String,Object> map = listDetail.get(i);
				if(StringUtils.isEmpty(map.get("DECLARE_PROVINCE_VALUE")+"")
				||"null".equals(map.get("DECLARE_PROVINCE_VALUE")+"")){
					resultFirst[i]=0f;
				} else{
					resultFirst[i] = float.parsefloat(map.get("DECLARE_PROVINCE_VALUE")+"");
				}
			}
		}
		Map<String,Object> enterprise= enterpriseQueryService.getInfoByOrgId(orgId).get(0);
		//根据 安徽省企业技术中心评价指标计算公式 进行算值 下一步算分
		float ratio1 = 0f;
		float ratio2 = 0f;
		float ratio3 = 0f;
		try {
			ratio1 = float.parsefloat(enterprise.get("RATIO1")+"");
			ratio2 = float.parsefloat(enterprise.get("RATIO2")+"");
			ratio3 = float.parsefloat(enterprise.get("RATIO3")+"");
		}
		catch (Exception e) {
		}
		Map<String,Object> 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 = 0f;
		List<Map<String,Object>> listScore = declareMasterService.queryScoreDic();
		for (int i = 0; i < listScore.size(); 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;
	}
}

说明:MyCallable仅仅是业务处理方式繁杂。可忽略,最后从390秒提速致40秒。

总结

以上就是本文关于Java多线程执行处理业务时间太久解决方法代码示例的全部内容,希望对大家有所帮助。感兴趣的朋友可以继续参阅本站其他相关专题,如有不足之处,欢迎留言指出。感谢朋友们对本站的支持!

(0)

相关推荐

  • java使用多线程读取超大文件

    接上次写的"JAVA读取超大文件".在读取超过10G的文件时会发现一次读一行的速度实在是不能接受,想到使用多线程+FileChannel来做一个使用多线程版本. 基本思路如下: 1.计算出文件总大小 2.分段处理,计算出每个线程读取文件的开始与结束位置 (文件大小/线程数)*N,N是指第几个线程,这样能得到每个线程在读该文件的大概起始位置 使用"大概起始位置",作为读文件的开始偏移量(fileChannel.position("大概起始位置"))

  • Java 多线程有序执行的几种方法总结

    Java 多线程有序执行的几种方法总结 同事无意间提出了这个问题,亲自实践了两种方法.当然肯定还会有更多更好的方法. 方法一 import java.util.concurrent.atomic.AtomicInteger; public class OrderedThread1 { static AtomicInteger count = new AtomicInteger(0); public static void main(String[] args) throws Interrupte

  • java使用CountDownLatch等待多线程全部执行完成

    前言 CountDownLatch 允许一个或多个线程等待其他线程完成操作. 应用场景 假如有一个列表的大量数据等待处理,最后全部处理完毕后返回处理结果.普通做法就是从头遍历,一个个顺序执行,这样单线程处理效率不高,我们希望使用多线程的方式处理,同时在主线程等待所有子线程处理完成. CountDownLatch的构造函数接收一个int类型的参数作为计数器,如果你想等待N个点完成,这里就传入N. 当我们调用一次CountDownLatch的countDown方法时,N就会减1,CountDownL

  • Java多线程下解决资源竞争的7种方法详解

    前言 一般情况下,只要涉及到多线程编程,程序的复杂性就会显著上升,性能显著下降,BUG出现的概率大大提升. 多线程编程本意是将一段程序并行运行,提升数据处理能力,但是由于大部分情况下都涉及到共有资源的竞争,所以修改资源 对象时必须加锁处理.但是锁的实现有很多种方法,下面就来一起了解一下在C#语言中几种锁的实现与其性能表现. 一.c#下的几种锁的运用方式 1.临界区,通过对多线程的串行化来访问公共资源或一段代码,速度快,适合控制数据访问. private static object obj = n

  • Java多线程按指定顺序同步执行

    笔者今天看到一个有趣的面试题,如何让多个线程按照既定的顺序依次执行?比如每个线程输出一个整数, 那么期望就是这样的:0,1,2,3,4,5,6,7,8,9. 而不是0,2,4,1,3,5,8,7,9,6 乍一看,这不是反人性的考题吗?多线程本来就以乱序执行出名的.稍加思索,想到3种解决方案,分别用代码实现之. 方法1 使用newSingleThreadExecutor newSingleThreadExecutor返回仅仅包含一个线程的线程池,将多个任务交给此Executor时,这个线程池处理完

  • Java多线程--让主线程等待所有子线程执行完毕在执行

    朋友让我帮忙写个程序从文本文档中导入数据到oracle数据库中,技术上没有什么难度,文档的格式都是固定的只要对应数据库中的字段解析就行了,关键在于性能. 数据量很大百万条记录,因此考虑到要用多线程并发执行,在写的过程中又遇到问题,我想统计所有子进程执行完毕总共的耗时,在第一个子进程创建前记录当前时间用System.currentTimeMillis()在最后一个子进程结束后记录当前时间,两次一减得到的时间差即为总共的用时,代码如下 long tStart = System.currentTime

  • 利用Java多线程技术导入数据到Elasticsearch的方法步骤

    前言 近期接到一个任务,需要改造现有从mysql往Elasticsearch导入数据MTE(mysqlToEs)小工具,由于之前采用单线程导入,千亿数据需要两周左右的时间才能导入完成,导入效率非常低.所以楼主花了3天的时间,利用java线程池框架Executors中的FixedThreadPool线程池重写了MTE导入工具,单台服务器导入效率提高十几倍(合理调整线程数据,效率更高). 关键技术栈 Elasticsearch jdbc ExecutorService\Thread sql 工具说明

  • java多线程处理执行solr创建索引示例

    复制代码 代码如下: public class SolrIndexer implements Indexer, Searcher, DisposableBean { //~ Static fields/initializers ============================================= static final Logger logger = LoggerFactory.getLogger(SolrIndexer.class); private static fi

  • Java多线程执行处理业务时间太久解决方法代码示例

    背景:在政府开发了一个应用系统,主要功能是让企业填写企业资质信息,然后通过给定的公式,统计这一系列的信息,以得分的形式展示给政府领导查看.目前有1300家企业填报.由于得分是实时显示的,所以导致统计功能很慢. 代码运行流程: 1.查出1300企业信息 2.遍历1300企业信息,ji计算每家企业得分信息.每家预计时间为0.3秒.合计390秒.导致页面请求超时 3.导出(用jxl jar) 解决方案: 由于处理业务的,所以需要能有返回值的线程.用:Callable 直接上代码 1.调用线程的代码 L

  • java获取当前时间的四种方法代码实例

    这篇文章主要介绍了java获取当前时间的四种方法代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 第一种:Date类 public class DateDemo { public static void main(String[] args) { Date day = new Date(); SimpleDateFormat dft = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); S

  • java定时器timer的使用方法代码示例

    1.首先肯定是容器一启动就要启动定时器,所以我们可以选择把定时器写在一个监听器里,容器一启动所以监听器也就跟着启动,然后定时器就可以工作了. 第一步,把自己写的监听器加到web.xml中: 第二步,写一个监听器,实现ServletContextListener接口: 第三步,写一个定时器,继承TimerTask,在复写的run()方法里写具体的业务逻辑. 第四步,在自己的监听器里复写的 public void contextInitialized(ServletContextEvent arg0

  • java加解密RSA使用方法代码示例

    最近为了分析一段请求流,不得不去研究一下RSA加密. 首先,强调一点:密钥的"钥"读"yue",不是"yao",额... 网上关于RSA的原理一抓一大把的,这里只是简单说说我的理解: 1. 两个足够大的互质数p, q: 2. 用于模运算的模 n=p*q: 3. 公钥KU(e, n)中的e满足 1<e< (p-1)(q-1),且与(p-1)(q-1)互质: 4. 密钥KR(d, n)中的d满足  d*e % (p-1)(q-1)= 1,

  • Java内存各部分OOM出现原因及解决方法(必看)

    一,jvm内存区域 1,程序计数器 一块很小的内存空间,作用是当前线程所执行的字节码的行号指示器. 2,java栈 与程序计数器一样,java栈(虚拟机栈)也是线程私有的,其生命周期与线程相同.通常存放基本数据类型,对象引用(一个指向对象起始地址的引用指针或一个代表对象的句柄),reeturnAddress类型(指向一条字节码指令的地址) 栈区域有两种异常类型:如果线程请求的栈深度大于虚拟机所允许的深度,将抛StrackOverflowError异常:如果虚拟机栈可以动态扩展(大部分虚拟机都可动

  • Java基于Runtime调用外部程序出现阻塞的解决方法

    本文实例讲述了Java基于Runtime调用外部程序出现阻塞的解决方法, 是一个很实用的技巧.分享给大家供大家参考.具体分析如下: 有时候在java代码中会调用一些外部程序,比如SwfTools来转换swf.ffmpeg来转换视频等.如果你的代码这样写:Runtime.getRuntime().exec(command),会发现程序一下就执行完毕,而在命令行里要执行一会,是因为java没有等待外部程序的执行完毕,此时就需要使用阻塞,来等待外部程序执行结果: InputStream stderr

  • Mac OS X 下 IntelliJ IDEA、jEdit 等 Java 程序中文标点输入无效的完美解决方法

    Mac OS X 下基于 Java 的程序(如 IntelliJ IDEA.jEdit 等)会出现中文标点输入无效的问题,在中文输入法状态,可以输入中文字,但输入中文标点最后上去的是英文标点.查阅了相关资料,原来这是 Java 自己的 bug.从 Java 8u51 版本开始就出现了这个 bug,一直到现在最新的 Java 8u72 仍然如此,但是老版本 Java 8u45 是没有这个问题的.所以,可以采取变通的方法,在 Mac OS X 上同时装一个老版本的 JDK 8u45,不会影响已经安装

  • java IO流将一个文件拆分为多个子文件代码示例

    文件分割与合并是一个常见需求,比如:上传大文件时,可以先分割成小块,传到服务器后,再进行合并.很多高大上的分布式文件系统(比如:google的GFS.taobao的TFS)里,也是按block为单位,对文件进行分割或合并. 看下基本思路: 如果有一个大文件,指定分割大小后(比如:按1M切割) step 1: 先根据原始文件大小.分割大小,算出最终分割的小文件数N step 2: 在磁盘上创建这N个小文件 step 3: 开多个线程(线程数=分割文件数),每个线程里,利用RandomAccessF

  • flyway实现java 自动升级SQL脚本的问题及解决方法

    为什么要用Flyway 在日常开发中,我们经常会遇到下面的问题: 自己写的SQL忘了在所有环境执行: 别人写的SQL我们不能确定是否都在所有环境执行过了: 有人修改了已经执行过的SQL,期望再次执行: 需要新增环境做数据迁移: 每次发版需要手动控制先发DB版本,再发布应用版本; 其它场景... 由于项目需求的变化,或者前期设计缺陷,导致在后期需要修改数据库,这应该是一个比较常见的事情,如果项目还没上线,你可能把表删除了重新创建,但是如果项目已经上线了,就不能这样简单粗暴了,每次运维部署项目,还得

  • java并发请求下数据插入重复问题的解决方法

    目录 前言 分布式锁工具类 在过滤器实现请求拦截 总结 前言 前段时间发现数据库里经常会存在两条相同的用户数据,导致数据查询异常.查了原因,发现前端微信小程序在授权登录时,有时会出现同时发送了两条一模一样的请求(也就是常说的并发).虽然后端代码有做防重复的判断,但是避免不了并发时候的重复性操作.于是就开始考虑并发的解决方案,解决方案有很多,从拦截请求到数据库层面都可以入手. 我们采用了对请求报文生成摘要信息+Redis分布式锁的方案.运行了一段时间,功能很可靠,代码也很简洁.于是上来做下记录以便

随机推荐