`
umgsai
  • 浏览: 110703 次
  • 性别: Icon_minigender_1
  • 来自: 广州
文章分类
社区版块
存档分类
最新评论

多线程优化

阅读更多
   public void newExecute() {
        //获取线程数,默认30
        int threadNum = 30;
        String strThreadNum = LionConfigUtils.getProperty("ts-monitor-job.dailyJob.accountBalanceDailyCheckerThreadNum",
                "");
        if (isNumeric(strThreadNum)) {
            threadNum = Integer.parseInt(strThreadNum);
        }
        ExecutorService service = Executors.newFixedThreadPool(threadNum);
        //所有账号总数
        int accountCount = accountDao.findAllMerchantAccountCount();
        int latchCount = accountCount % BATCH_SIZE == 0 ? accountCount / BATCH_SIZE : (accountCount / BATCH_SIZE + 1);
        final CountDownLatch latch = new CountDownLatch(latchCount);
        final Date bizDate = DateUtils.addDate(DateUtils.removeTime(new Date()), -1);
        final Date lastBizDate = DateUtils.addDate(bizDate, -1);
        int offset = 0;
        while (offset < accountCount) {
            offset += BATCH_SIZE;
            final int initPage = offset;
            Runnable run = new Runnable() {
                public void run() {
                    try {
                        //todo
                        List<AccountData> accountDataList = accountDao.findAllMerchantAccount(initPage, BATCH_SIZE);
                        for (AccountData accountData : accountDataList) {
                            Thread.sleep(20);
                            doAccountMonitor(bizDate, lastBizDate, accountData);
                        }
                    } catch (Exception e) {
                        monitorLogger.error(String.format("severity=[1], query account data list fail! offset = " +
                                "[%d]...", initPage), e);
                    } finally {
                        latch.countDown();
                    }
                }
            };
            service.submit(run);
        }

        try {
            latch.await();
        } catch (InterruptedException e) {
            monitorLogger.error("CountDownLatch.await() error:" + e);
        }
    }

 上面的代码没起到优化作用,下面的代码优化比较好

public String execute() throws Exception {

		String timeFlag=LionConfigUtils.getProperty("ts-tg-settle-service.tgSettleGroupJob.timeFlag");
		int  sleepTime= Integer.parseInt(LionConfigUtils.getProperty("ts-tg-settle-service.tgSettleGroupJob.sleepTime"));
		//生成查询的初始时间和结束时间
		String startTime=null;
		String endTime=null;
		String timelist[]=	generateTargetDate(timeFlag);
		startTime=timelist[0];
		endTime=timelist[1];
		//把要查询的状态封装入list 默认只查init类型
		List<Integer> statusList=new ArrayList<Integer>();
		statusList.add(GroupSettleStatus.INIT.getCode());
		//便利group表,一边遍历一边发消息
		//todo 分页 dao写sql 每页大小lion配置

		//分页数据 startRow endRow pageSize 注意,pagesize从lion获取,检验一下是否为数字
		int startRow=0;

		int pageSize=10;
		//线程数默认30个先
		int threadNum=30;

		String  strPageSize= LionConfigUtils.getProperty("ts-tg-settle-service.tgSettleGroupJob.pageSize");

		if(isNumeric(strPageSize)){
			pageSize=Integer.parseInt(strPageSize);
		}
		String strThreadNum= LionConfigUtils.getProperty("ts-tg-settle-service.tgSettleGroupJob.groupThreadNum");
		if(isNumeric(strThreadNum)){
			threadNum=Integer.parseInt(strThreadNum);
		}


		ExecutorService service = Executors.newFixedThreadPool(threadNum);

		//得到所有要发的数量和latch数量。
		int resultCount=tstgSettleGroupDao.selectCountSettleGroupToTuanGouJob(startTime,endTime,statusList);
		int latchCount=0;
		if(resultCount%pageSize==0){
			latchCount=resultCount/pageSize;
		}else{
			latchCount=resultCount/pageSize+1;
		}
		CountDownLatch latch=new CountDownLatch(latchCount);

		//查询每页数据并发送 直到查没有了
        int lastId = 0;
        List<TSTGSettleGroupEntity> entityList = null;
		while(true){
            if(lastId == 0){
                entityList = tstgSettleGroupDao.selectSettleGroupToTuanGouJobByAddTime(startRow,pageSize,startTime,endTime,statusList,lastId);
            }else{
                entityList=tstgSettleGroupDao.selectSettleGroupToTuanGouJob(startRow,pageSize,startTime,endTime,statusList,lastId);
            }

			if(CollectionUtils.isEmpty(entityList)){
				break;
			}
			//logger.info(times+" send group : pageSize: "+pageSize +"  startRow:"+startRow +"  startTime: "+startTime+"  endTime: "+endTime);
			//System.out.println(lastId+" send group : pageSize: "+pageSize +"  startRow:"+startRow +"  startTime: "+startTime+"  endTime: "+endTime);
            service.submit(new ManageListAndSendThread(tstgSettleGroupDao,entityList,settleAccountMessageProducer,latch,sleepTime));
            lastId = entityList.get(entityList.size() - 1).getId();
		}
        try {
            latch.await();
        }catch (Exception e){
            logger.error("latch await error!"+e.getMessage());
        }

		return null;
	}

 

public class ManageListAndSendThread implements Runnable{
///.............省略部分代码
    @Override
    public void run() {
        try{
            for(TSTGSettleGroupEntity entity:entityList){

                TuanGouSettleAccountMessageDTO messageDTO=transformSettleEntityToMessageDTO(entity, ResourceType.GROUP.getIdentifier());

                logger.info(" i send outBizId :"+messageDTO.getOutBizId()+" threadName:"+Thread.currentThread().getName());

                    //大量数据下出现个案 所以逻辑改为先修改状态再发送
                    //把entity 状态改为发送中
                    TSTGSettleGroupEntity temp=new TSTGSettleGroupEntity();
                    temp.setId(entity.getId());
                    temp.setSettleStatus(GroupSettleStatus.SETTLING.getCode());
                    tstgSettleGroupDao.update(temp);
                    logger.info("状态修改为已发送,groupId为:"+entity.getId());
                    temp=null;
                    sendTgGroupSettle(messageDTO);
                    logger.info("消息已发送,groupId为:"+entity.getId());

                try {
                    Thread.sleep(sleepTime);
                }catch (Exception e){

                }
            }
        }finally {
            //计数器减一
            latch.countDown();
        }
    }
}

 

这段代码结合多线程对大数据量下的分页查询进行了优化,SQL语句参考下面

SELECT ID,AccountID,AccountType,AccountSubject,Credit,Debit,STATUS,IsBuffer,AccountDirection,Balance,FrozenBalance,ADDTIME,UpdateTime
        FROM Account
        WHERE AccountType = 2
        ORDER BY ID
        LIMIT 1825000, 10;
SELECT ID,AccountID,AccountType,AccountSubject,Credit,Debit,STATUS,IsBuffer,AccountDirection,Balance,FrozenBalance,ADDTIME,UpdateTime
        FROM Account
        WHERE AccountType = 2 AND id >= 2790048
        ORDER BY ID ASC
        LIMIT 10;
SELECT ID,AccountID,AccountType,AccountSubject,Credit,Debit,STATUS,IsBuffer,AccountDirection,Balance,FrozenBalance,ADDTIME,UpdateTime
        FROM Account 
        WHERE AccountType = 2 AND id >(
		SELECT id FROM  Account ORDER BY id LIMIT 1825000,1       
        ) ORDER BY id LIMIT 10;

 

分享到:
评论

相关推荐

    FFmpegH264 多线程 优化

    综上所述,"FFmpegH264 多线程 优化"项目旨在通过多线程技术与硬件加速指令(如MMX、SSE和AVX)的结合,提升FFmpeg在解码H264视频流时的性能。这对于处理高清、高帧率视频或实时流媒体应用尤其重要,能够确保视频...

    Java多线程优化百万级数据

    通过对这些代码的分析和学习,我们可以更好地理解和应用Java多线程优化技巧。 总结来说,Java多线程优化在处理百万级数据时扮演着关键角色。通过合理地拆分任务、使用线程池、选择合适的并发容器和同步机制,以及...

    Aria2下载器.zip(多线程优化版)win10可用

    标题中的"Aria2下载器.zip(多线程优化版)win10可用"指的是一个针对Windows 10操作系统优化过的Aria2下载工具的压缩包。Aria2是一款开源、轻量级且功能强大的下载管理器,支持多种协议,如HTTP(S)、FTP、SFTP、...

    基于AVX256指令集和多线程优化的双机计算加速程序

    【基于AVX256指令集和多线程优化的双机计算加速程序】是一个C++编程项目,利用了先进的处理器指令集AVX256和多线程技术来提升计算性能,尤其适用于大规模数据处理和高性能计算场景。在VS2019环境下开发,项目实现了...

    Python 计算从1-N(N可以任何数)内的素数(并行计算、多线程优化计算)

    Python 计算从1-N(N可以任何数)内的素数(并行计算、多线程优化计算)

    C#多线程优化教程资源及代码

    C#多线程优化教程资源及代码,

    Java多线程优化方法及使用方式

    Java多线程优化方法及使用方式 Java多线程优化方法及使用方式可以分为以下几个方面: 一、多线程介绍 在编程中,我们不可逃避的会遇到多线程的编程问题,因为在大多数的业务系统中需要并发处理,如果是在并发的...

    多线程优化,加实例。多多有益

    玩转多线程文档,加实例,可运行。专家鉴定

    java多线程导出excel(千万级别)优化

    Java多线程导出Excel是处理大数据量时的一种高效策略,尤其在面对千万级别的数据时。传统的Apache POI库在处理大规模数据时可能会遇到栈溢出(StackOverflowError)和内存溢出(OutOfMemoryError)等问题,因为这些...

    Android 多线程优化方略

    android高级进阶之多线程的优化方略,里面包含一个视频还有一个图片笔记,希望想提高自己水平的同学能有所收获

    基于C++多线程优化与Python调用的ndt_omp_lib设计源码

    本项目是一个针对NDT匹配和多线程技术的C++源码,通过优化设计实现了高效的线程管理和Python调用。项目包含103个文件,涵盖C++源码、CMake构建脚本、Shell和Python脚本等,并特别设计了一个可由Python调用的.so动态...

    Unity多线程工具类

    5. **多线程优化**: 在使用多线程时,需要注意避免数据竞争和死锁。Unity的Job System会自动处理这些情况,但在使用Coroutine或UnityMainThreadDispatcher时,开发者需要手动管理同步。另外,尽量减少跨线程的数据...

    易语言超级列表框多线程源码

    总的来说,这个易语言的示例程序为我们提供了一个在处理大型数据集合时如何利用多线程优化超级列表框性能的方法。通过学习和分析这段源码,开发者可以更好地掌握易语言的多线程编程技巧,提升自己的程序设计能力。

    多线程矩阵乘法C++源代码

    在编程领域,多线程是一种常见...通过深入理解以上知识点,开发者可以学习到如何在C++环境中使用多线程优化计算密集型任务,特别是矩阵乘法这一典型问题。这个项目对于理解并发编程和提高程序效率具有很高的教育价值。

    多进程多线程快速排序C++源码

    通过分析这个项目,开发者可以深入学习多进程、多线程编程技巧,以及如何在实际应用中优化算法性能。此外,对于想要提高自己在并发编程和系统级编程能力的C++开发者来说,这是一个很好的实践案例。

    简单的多线程程序

    在编程领域,多线程是一种常见且重要的技术...结合MFC和OpenCV,我们可以构建复杂的图像处理系统,利用多线程优化性能,提高用户体验。而"more_line_0722"文件的代码应该能提供具体的操作实例,帮助深入理解这一主题。

    java用多线程进行排序算法的比较

    通过分析这些代码,你可以深入理解如何在实际项目中应用多线程优化排序算法,并学习如何平衡并行化带来的收益与额外的系统开销。 总之,Java的多线程特性为实现高效的排序算法提供了可能。通过合理地使用多线程,...

    springboot 文件转换PDF多线程

    根据网上的资料总结的一个springboot 转换pdf Word文档大小最好2m以下 需要安装OpenOffice.org 3.3 链接:https://pan.baidu.com/s/1onrkhBCNlGLEmf3hPwzXWw 密码:8h5a

Global site tag (gtag.js) - Google Analytics