今天被老大交给了一个任务,对数据库中原有的数据进行一定的操作,然后放入到另外一张表中。
那么我拿到这个任务,分析了下业务逻辑就开始编码了,经过一上午的代码开发,运行测试,功能完好,但是速度实在太慢了,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的利用度高了,速度也就快了。
另外,在使用以上线程池控制多线程时,线程的个数要设计好,系统创建和销毁线程也是需要一定时间的,设计优良,才能是多线程效果最大化。
第一次使用多线程,以前只是在学习的时候听老师讲个这个概念,现在记录下,希望大婶们多多提出宝贵的意见,共同学习,不胜感激!!!
相关推荐
JDK 自带线程池是 Java 语言中用于管理和执行线程的工具,旨在提高多线程编程的效率和灵活性。本文将详细介绍 JDK 自带线程池的组成、创建方法、优点和常见应用场景。 多线程技术 多线程技术是指在一个处理器单元...
- **线程池(ThreadPool)**:是一种多线程处理形式,处理过程中将任务添加到队列,然后在创建线程后自动启动这些任务。线程池中的线程可以被重复利用,减少了创建和销毁线程的开销。 - **工作队列(Work Queue)*...
`shutdown()`会等待所有已提交的任务执行完毕,而`shutdownNow()`则尝试取消正在执行的任务。 总结,这个"Java/Android线程池演示Demo"旨在通过实例展示如何在Android和Java项目中使用线程池进行并发处理,帮助...
jdk自带的线程池是Java开发中一个非常重要的概念,特别是在多线程编程中。线程池是线程的容器,每次只执行额定数量的线程,线程池就是用来管理这些额定数量的线程。下面我们来详细了解jdk自带的线程池。 一、jdk...
理解并熟练运用线程池是Java多线程编程中的重要技能,能够帮助开发者更有效地管理并发,提高系统的效率和稳定性。通过合理配置线程池参数,结合业务场景选择合适的阻塞队列和饱和策略,可以实现高性能的并发处理。
在Java编程中,多线程读取多个文件是一项常见需求,尤其在文件数量较多或者文件较大时,能够提升处理效率。本文将详细介绍如何在Java中使用多线程来同时读取多个文件。 首先,本文涉及到的核心类是`Thread`类,这是...
下面将从多线程编程的基础知识、线程池的使用、异常捕获三个方面进行阐述。 一、多线程编程基础知识 在 Java 中,存在两种线程模型:主线程和子线程。主线程是程序的入口点,而子线程是由主线程创建的辅助线程。...
同时,Spring框架提供的线程池功能则可以帮助我们优化多线程环境下的性能,特别是处理并发请求时。在这个主题中,我们将深入探讨如何利用Spring MVC与Spring线程池来有效地管理并发请求,并解决数据同步控制问题。 ...
在Java中,多线程编程允许程序同时执行多个任务,提高程序的执行效率。然而,多线程也带来了同步问题,如竞态条件、死锁等,因此,对线程的监控显得至关重要。 二、JVM内置的线程监控 1. **JConsole**: JConsole是...
最后,工具在Java多线程开发中也起着重要作用,例如JVisualVM、JConsole等Java自带的监控工具,可以帮助开发者分析线程状态、检测死锁、查看内存使用情况等,从而更好地理解和优化多线程程序。 总之,Java多线程...
Java自带的并发框架通过提供高级的并发工具和类,使开发者能够更安全、更高效地编写多线程程序,避免了直接操作底层并发原语带来的复杂性和潜在风险。通过理解和熟练使用这些工具,我们可以构建出更健壮、更具伸缩性...
目前,主要有两种方式可以实现定时任务:一种是Java自带的定时任务实现,另一种是通过第三方框架实现。在这两种方式中,Spring框架提供了自己的定时任务工具Spring Task,以及与专业定时任务框架Quartz集成的能力。 ...
而多线程则允许多个任务同时执行,每个任务称为一个线程。这使得程序能够更高效地利用CPU资源,尤其是在处理I/O密集型或计算密集型任务时。 在Linux操作系统中,多线程通过内核级的线程管理实现,如POSIX线程...
- **调试技巧**:多线程调试比较复杂,可以使用JDK自带的调试工具,如JVisualVM等,来帮助分析线程的状态和行为。 通过以上内容的学习,读者可以深入了解Java线程的高级使用方法,掌握如何在Java程序中高效地管理和...
线程池是可以容纳多个线程的容器,程序可以从线程池获取线程来完成目标代码,同时也可以将线程归还给线程池,省去了创建线程和销毁线程这样非常繁琐的操作。 2、线程池的使用 public static ExecutorService ...
线程池是一种多线程处理形式,处理过程中将任务添加到队列,然后在创建线程后自动启动这些任务。它可以控制运行的线程数量,当线程超过一定数量时,新任务将会等待,直到有线程空闲出来。这样可以有效地避免系统资源...
在线程池中,线程池可以管理一堆线程,让线程执行完任务之后不会进行销毁,而是继续去处理其它线程已经提交的任务。 使用线程池的好处有: * 降低资源消耗。通过重复利用已创建的线程降低线程创建和销毁造成的消耗...
- **任务并发控制**:确保多个任务执行时的互斥和资源管理,避免并发问题。 - **异常处理**:对可能出现的异常进行捕获和处理,防止任务中断。 - **任务状态管理**:记录任务执行历史,便于监控和调试。 - **灵活性*...
1. **多线程概念**:多线程是程序执行时的一种并发机制,可以让程序同时执行多个不同的任务。在Android系统中,主线程(UI线程)负责处理用户交互和界面更新,而其他工作线程则用来执行耗时操作,如文件下载,以避免...
线程池是Java中的一种多线程编程模式,用于提高程序的执行效率和响应速度。 SpringBoot2框架提供了ThreadPoolTaskExecutor来实现线程池的定义和使用。 线程池的定义 在SpringBoot2中,我们可以通过定义...