`
guyunduzai
  • 浏览: 17471 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论
阅读更多

今天被老大交给了一个任务,对数据库中原有的数据进行一定的操作,然后放入到另外一张表中。

那么我拿到这个任务,分析了下业务逻辑就开始编码了,经过一上午的代码开发,运行测试,功能完好,但是速度实在太慢了,1000万的数据量执行了5个小时,速度必须要提上来,这时候我想到了使用多线程。

    但是问题来了,我之前没有使用过多线程,怎么办呢,百度。经过百度后,我尝试着使用java提供的线程池管理线程,进行重构这个功能,其中利用线程池管理多线程进行开发的主要代码如下:

public class ThreadWork {
    public void workWithThreads() {
        // 用线程池,开启20个线程
        ExecutorService threadPool = Executors.newFixedThreadPool(20);
        CompletionService<String> pool = new ExecutorCompletionService<String>(threadPool);
        String result = null;
        boolean flag = true;
        // 从数据库获取数据(10000条)
        List<String> ids = new ArrayList<>();// from database
        while (true) {
            if (ids != null && ids.size() > 0) {
                // 如果从数据库中取出数据为10000条,分20个线程执行,如果不够10000条,单线程执行
                if (ids.size() == 10000) {
                    for (int p = 1; p < 21; p++) {
                        pool.submit((Callable<String>) new ThreadTask(ids.subList(500 * (p - 1), 500 * p)));
                    }
                } else {
                   pool.submit((Callable<String>)new ThreadTask(ids));
                    // 因为从数据库中每次fetch first 1W条,所以当条数不等于1W条时,说明是最后一次从数据库中取数据
                    flag = false;
                }
                // 以下循环为保证所有线程执行结束
                for (int p = 1; p < 21; p++) {
                    try {
                        result = pool.take().get();
                    } catch (Exception e) {
                        // 打印错误日志 TODO
                    }
                }
            }
        }
    }
}

 

 每个线程需要做的业务逻辑在ThreadTask类中,代码如下:

public class ThreadTask implements Callable<String> {
    private List<String> ids;

    public ThreadTask(List<String> ids) {
        this.ids = ids;
    }

    @Override
    public String call() throws Exception {
        // 获取参数,执行响应的操作
        for(String id:ids){
            // 此处为对数据的操作
            System.out.println(id);
        }
        // 返回改线程的id
        return Thread.currentThread() + "";
    }
}

 经过上面多线程的处理,整个功能的速度的确提升了很高。

说到底,多线程速度快是因为最大限度的使用了cpu,执行的还是顺序的,只是利用了单线程中cpu等待、挂起等等的一些时间,cpu的利用度高了,速度也就快了。

 

另外,在使用以上线程池控制多线程时,线程的个数要设计好,系统创建和销毁线程也是需要一定时间的,设计优良,才能是多线程效果最大化。

 

第一次使用多线程,以前只是在学习的时候听老师讲个这个概念,现在记录下,希望大婶们多多提出宝贵的意见,共同学习,不胜感激!!!

2
0
分享到:
评论
4 楼 guyunduzai 2014-12-05  
cywhoyi 写道
如果你是是在双核下开20个线程,我觉得你不妨尝试用10个线程左右,估计效率更加快。
线程数量跟intel内核有正比关系,也跟你单个线程执行的任务有关系,不要盲目开20个线程,线程上下文切换,时间片的轮转都会导致效率下降很多



是这样的
3 楼 guyunduzai 2014-12-05  
cugbzc 写道
写个存储过程,然后再用JAVA调起来,那用费这么多事儿


存储过程?求指教,我还真没用过,可以邮箱联系guyunduzai@sina.cn
2 楼 cywhoyi 2014-11-27  
如果你是是在双核下开20个线程,我觉得你不妨尝试用10个线程左右,估计效率更加快。
线程数量跟intel内核有正比关系,也跟你单个线程执行的任务有关系,不要盲目开20个线程,线程上下文切换,时间片的轮转都会导致效率下降很多
1 楼 cugbzc 2014-11-27  
写个存储过程,然后再用JAVA调起来,那用费这么多事儿

相关推荐

    JDK自带线程池分析

    JDK 自带线程池是 Java 语言中用于管理和执行线程的工具,旨在提高多线程编程的效率和灵活性。本文将详细介绍 JDK 自带线程池的组成、创建方法、优点和常见应用场景。 多线程技术 多线程技术是指在一个处理器单元...

    线程池管理多线程上传

    - **线程池(ThreadPool)**:是一种多线程处理形式,处理过程中将任务添加到队列,然后在创建线程后自动启动这些任务。线程池中的线程可以被重复利用,减少了创建和销毁线程的开销。 - **工作队列(Work Queue)*...

    Java/Android线程池演示Demo

    `shutdown()`会等待所有已提交的任务执行完毕,而`shutdownNow()`则尝试取消正在执行的任务。 总结,这个"Java/Android线程池演示Demo"旨在通过实例展示如何在Android和Java项目中使用线程池进行并发处理,帮助...

    jdk自带线程池实例详解

    jdk自带的线程池是Java开发中一个非常重要的概念,特别是在多线程编程中。线程池是线程的容器,每次只执行额定数量的线程,线程池就是用来管理这些额定数量的线程。下面我们来详细了解jdk自带的线程池。 一、jdk...

    JAVA线程池的分析和使用

    理解并熟练运用线程池是Java多线程编程中的重要技能,能够帮助开发者更有效地管理并发,提高系统的效率和稳定性。通过合理配置线程池参数,结合业务场景选择合适的阻塞队列和饱和策略,可以实现高性能的并发处理。

    java多线程读取多个文件的方法

    在Java编程中,多线程读取多个文件是一项常见需求,尤其在文件数量较多或者文件较大时,能够提升处理效率。本文将详细介绍如何在Java中使用多线程来同时读取多个文件。 首先,本文涉及到的核心类是`Thread`类,这是...

    子线程任务发生异常,主线程事务如何回滚

    下面将从多线程编程的基础知识、线程池的使用、异常捕获三个方面进行阐述。 一、多线程编程基础知识 在 Java 中,存在两种线程模型:主线程和子线程。主线程是程序的入口点,而子线程是由主线程创建的辅助线程。...

    springmvc+spring线程池处理http并发请求数据同步控制问题

    同时,Spring框架提供的线程池功能则可以帮助我们优化多线程环境下的性能,特别是处理并发请求时。在这个主题中,我们将深入探讨如何利用Spring MVC与Spring线程池来有效地管理并发请求,并解决数据同步控制问题。 ...

    java 监控线程

    在Java中,多线程编程允许程序同时执行多个任务,提高程序的执行效率。然而,多线程也带来了同步问题,如竞态条件、死锁等,因此,对线程的监控显得至关重要。 二、JVM内置的线程监控 1. **JConsole**: JConsole是...

    java多线程

    最后,工具在Java多线程开发中也起着重要作用,例如JVisualVM、JConsole等Java自带的监控工具,可以帮助开发者分析线程状态、检测死锁、查看内存使用情况等,从而更好地理解和优化多线程程序。 总之,Java多线程...

    java自带并发框架

    Java自带的并发框架通过提供高级的并发工具和类,使开发者能够更安全、更高效地编写多线程程序,避免了直接操作底层并发原语带来的复杂性和潜在风险。通过理解和熟练使用这些工具,我们可以构建出更健壮、更具伸缩性...

    Spring 框架自带定时任务和Quartz定时任务

    目前,主要有两种方式可以实现定时任务:一种是Java自带的定时任务实现,另一种是通过第三方框架实现。在这两种方式中,Spring框架提供了自己的定时任务工具Spring Task,以及与专业定时任务框架Quartz集成的能力。 ...

    多线程相关文档

    而多线程则允许多个任务同时执行,每个任务称为一个线程。这使得程序能够更高效地利用CPU资源,尤其是在处理I/O密集型或计算密集型任务时。 在Linux操作系统中,多线程通过内核级的线程管理实现,如POSIX线程...

    Java线程 高级使用

    - **调试技巧**:多线程调试比较复杂,可以使用JDK自带的调试工具,如JVisualVM等,来帮助分析线程的状态和行为。 通过以上内容的学习,读者可以深入了解Java线程的高级使用方法,掌握如何在Java程序中高效地管理和...

    Java中的线程池以及Lambda表达式的应用

    线程池是可以容纳多个线程的容器,程序可以从线程池获取线程来完成目标代码,同时也可以将线程归还给线程池,省去了创建线程和销毁线程这样非常繁琐的操作。 2、线程池的使用 public static ExecutorService ...

    android 线程池下载

    线程池是一种多线程处理形式,处理过程中将任务添加到队列,然后在创建线程后自动启动这些任务。它可以控制运行的线程数量,当线程超过一定数量时,新任务将会等待,直到有线程空闲出来。这样可以有效地避免系统资源...

    7000字+24张图带你彻底弄懂线程池.doc

    在线程池中,线程池可以管理一堆线程,让线程执行完任务之后不会进行销毁,而是继续去处理其它线程已经提交的任务。 使用线程池的好处有: * 降低资源消耗。通过重复利用已创建的线程降低线程创建和销毁造成的消耗...

    java定时任务

    - **任务并发控制**:确保多个任务执行时的互斥和资源管理,避免并发问题。 - **异常处理**:对可能出现的异常进行捕获和处理,防止任务中断。 - **任务状态管理**:记录任务执行历史,便于监控和调试。 - **灵活性*...

    Android多线程下载器

    1. **多线程概念**:多线程是程序执行时的一种并发机制,可以让程序同时执行多个不同的任务。在Android系统中,主线程(UI线程)负责处理用户交互和界面更新,而其他工作线程则用来执行耗时操作,如文件下载,以避免...

    SpringBoot2线程池定义使用方法解析

    线程池是Java中的一种多线程编程模式,用于提高程序的执行效率和响应速度。 SpringBoot2框架提供了ThreadPoolTaskExecutor来实现线程池的定义和使用。 线程池的定义 在SpringBoot2中,我们可以通过定义...

Global site tag (gtag.js) - Google Analytics