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

时间: 2017-12-04

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 多线程有序执行的几种方法总结

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使用多线程读取超大文件

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

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多线程下解决资源竞争的7种方法详解

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

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

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

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

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

Java中CountDownLatch进行多线程同步详解及实例代码

Java中CountDownLatch进行多线程同步详解 CountDownLatch介绍 在前面的Java学习笔记中,总结了Java中进行多线程同步的几个方法: 1.synchronized关键字进行同步. 2.Lock锁接口及其实现类ReentrantLock.ReadWriteLock锁实现同步. 3.信号量Semaphore实现同步. 其中,synchronized关键字和Lock锁解决的是多个线程对同一资源的并发访问问题.信号量Semaphore解决的是多副本资源的共享访问问题. 今天

详解Java Callable接口实现多线程的方式

在Java 1.5以前,创建线程的2种方式,一种是直接继承Thread,另外一种就是实现Runnable接口.无论我们以怎样的形式实现多线程,都需要调用Thread类中的start方法去向操作系统请求io,cup等资源.因为线程run方法没有返回值,如果需要获取执行结果,就必须通过共享变量或者使用线程通信的方式来达到效果,这样使用起来就比较麻烦. 而自从Java 1.5开始,就提供了Callable和Future,通过它们可以在任务执行完毕之后得到任务执行结果. Callable和Future介

Java编程利用socket多线程访问服务器文件代码示例

这篇文章将向大家展示Java编程利用socket多线程访问服务器文件代码示例,如果您想先了解Java多线程socket编程的基础知识,可以看下这篇文章:Java多线程编程实现socket通信示例代码. 接下来进入正文,我们看看利用socket多线程访问服务器代码: ServerMain.java package com.ysk.webServer; import java.io.File; import java.io.IOException; import java.net.ServerSoc

浅谈Java的两种多线程实现方式

本文介绍了浅谈Java的两种多线程实现方式,分享给大家.具有如下: 一.创建多线程的两种方式 Java中,有两种方式可以创建多线程: 1 通过继承Thread类,重写Thread的run()方法,将线程运行的逻辑放在其中 2 通过实现Runnable接口,实例化Thread类 在实际应用中,我们经常用到多线程,如车站的售票系统,车站的各个售票口相当于各个线程.当我们做这个系统的时候可能会想到两种方式来实现,继承Thread类或实现Runnable接口,现在看一下这两种方式实现的两种结果. 程序1

java selenium智能等待页面加载完成示例代码

java selenium  智能等待页面加载完成 我们经常会碰到用selenium操作页面上某个元素的时候, 需要等待页面加载完成后, 才能操作.  否则页面上的元素不存在,会抛出异常. 或者碰到AJAX异步加载,我们需要等待元素加载完成后, 才能操作 selenium 中提供了非常简单,智能的方法,来判断元素是否存在. 阅读目录 实例要求 隐式等待 显式等待 实例要求 实例:set_timeout.html 下面的html 代码,  点击click 按钮5秒后, 页面上会出现一个红色的div

java 中线程等待与通知的实现

java 中线程等待与通知的实现 前言: 关于等待/通知,要记住的关键点是: 必须从同步环境内调用wait().notify().notifyAll()方法.线程不能调用对象上等待或通知的方法,除非它拥有那个对象的锁. wait().notify().notifyAll()都是Object的实例方法.与每个对象具有锁一样,每个对象可以有一个线程列表,他们等待来自该信号(通知).线程通过执行对象上的wait()方法获得这个等待列表.从那时候起,它不再执行任何其他指令,直到调用对象的notify()

Java使用Thread创建多线程并启动操作示例

本文实例讲述了Java使用Thread创建多线程并启动操作.分享给大家供大家参考,具体如下: 按照教程实现了一个单线程的创建,但是单线程的创建于启动并不是很有实用价值的.毕竟直接在main方法中放着相关的执行操作本身也就是一种单线程的实现.接下来在之前用过的代码基础上稍作修改,形成如下代码: class ThreadDemo extends Thread { ThreadDemo(){}; ThreadDemo(String szName) { super(szName); } public v

python等待10秒执行下一命令的方法

python等待10秒执行下一命令的方法: 首先导入时间(time)模块: 然后在需要等待执行的命令前调用sleep()方法,并在方法的括号里将等待时间设置为10秒即可. import time print '10秒前' time.sleep(10) print '10秒后' 先打印10秒前,等待10秒后,打印10秒后. 内容扩展: 不用多线程的话,可以用信号来解决这个问题. # -*- coding: utf-8 -*- import signal class InputTimeoutErro