线程池被创建里有线程吗(每日一问(十五)说说你对线程池的理解)

本文目录
- 每日一问(十五)说说你对线程池的理解
- java中线程池里面跑的线程还能创建自己的线程池吗这样做有什么害处
- 如何创建一个线程如何启动一个线程池
- 使用了线程池还需要创建线程吗
- 线程池的创建方式有几种
- 【Java基础】线程池的原理是什么
- Android线程池的使用
- 什么叫线程池线程池如何使用
- 线程与线程池
每日一问(十五)说说你对线程池的理解
减少了创建和销毁线程的次数,每个工作线程都可以被重复利用,可执行多个任务。
可以根据系统的承受能力,调整线程池中工作线线程的数目,防止因为消耗过多的内存,(每个线程需要大约1MB内存,线程开的越多,消耗的内存也就越大)。
线程池都是通过Executors来创建的。
new CachedThreadPool 创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
new FixedThreadPool 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
new ScheduledThreadPool 创建一个定长线程池,支持定时及周期性任务执行。
new SingleThreadExecutor 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序执行。
corePoolSize: 线程池维护线程的最少数量。
maximumPoolSize:线程池维护线程的最大数量。
keepAliveTime: 线程池维护线程所允许的空闲时间。
workQueue: 线程池所使用的缓冲队列。
handler: 线程池对拒绝任务的处理策略。
创建规则: 一个任务通过execute(Runnable)方法欲添加到线程池时:
如果此时线程池中的数量小于corePoolSize,即使线程池中的线程都处于空闲状态,也要创建新的线程来处理被添加的任务。
如果此时线程池中的数量等于 corePoolSize,但是缓冲队列 workQueue未满,那么任务被放入缓冲队列。
如果此时线程池中的数量大于corePoolSize,缓冲队列workQueue满,并且线程池中的数量小于maximumPoolSize,建新的线程来处理被添加的任务。
如果此时线程池中的数量大于corePoolSize,缓冲队列workQueue满,并且线程池中的数量等于maximumPoolSize,那么通过 handler所指定的策略来处理此任务。也就是:处理任务的优先级为:核心线程corePoolSize、任务队列workQueue、最大线程maximumPoolSize,如果三者都满了,使用handler处理被拒绝的任务。
当线程池中的线程数量大于 corePoolSize时,如果某线程空闲时间超过keepAliveTime,线程将被终止。这样,线程池可以动态的调整池中的线程数。
hreadPoolExecutor提供了两个方法,用于线程池的关闭,分别是shutdown()和shutdownNow(),其中:
Shutdown():不会立即终止线程池,而是要等所有任务缓存队列中的任务都执行完后才终止,但再也不会接受新的任务。
ShutdownNow():立即终止线程池,并尝试打断正在执行的任务,并且清空任务缓存队列,返回尚未执行的任务。
java中线程池里面跑的线程还能创建自己的线程池吗这样做有什么害处
当然可以,没什么害处。 给你个简单例子: J2EE的服务器里每个应用都是子线程再加上一堆孙线程里实现的。而自己的代码,还会在孙线程里再建立重孙线程。
如何创建一个线程如何启动一个线程池
果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了,这样频繁创建线程就会大大降低系统的效率,因为频繁创建线程和销毁线程需要时间。
那么有没有一种办法使得线程可以复用,就是执行完一个任务,并不被销毁,而是可以继续执行其他的任务?
在Java中可以通过线程池来达到这样的效果。今天我们就来详细讲解一下Java的线程池,首先我们从最核心的ThreadPoolExecutor类中的方法讲起,然后再讲述它的实现原理,接着给出了它的使用示例,最后讨论了一下如何合理配置线程池的大小。
以下是本文的目录大纲:
一.Java中的ThreadPoolExecutor类
二.深入剖析线程池实现原理
三.使用示例
四.如何合理配置线程池的大小
若有不正之处请多多谅解,并欢迎批评指正。
请尊重作者劳动成果,转载请标明原文链接:
使用了线程池还需要创建线程吗
使用了线程池,不需要手动创建线程,线程池会自动管理线程的创建和销毁。
需要注意的是:
线程池的大小需要根据实际情况进行设置,过小会导致任务无法及时处理,过大会占用过多的资源。
线程池中的线程需要注意线程安全,避免出现竞态条件等问题。
对于长时间运行的任务,需要考虑定期检查线程池中的线程是否存在问题(如死锁、阻塞等),及时进行处理。
线程池中的任务需要合理分配,避免出现某个任务长时间占用线程导致其他任务无法及时处理的情况。
在使用线程池时,需要注意线程的优先级、线程的命名等问题,以便进行调试和排查问题。
线程池的创建方式有几种
线程池是一种常见的多线程并发处理技术,它可以在需要执行任务的时候为任务提供一个线程,从而避免了每次执行任务都需要创建一个新的线程的开销。线程池的创建方式有几种,其中最常见的是使用ThreadPoolExecutor类来创建线程池。
ThreadPoolExecutor类是Java中的一个内置类,它可以用于创建和管理线程池。这个类提供了很多有用的方法和属性,例如可以指定线程池的大小、最大线程数、线程空闲时间等参数。另外,它还提供了一些方法用于提交任务到线程池,并且它会自动管理线程池中的线程,包括创建、销毁和重用等操作。
除了使用ThreadPoolExecutor类来创建线程池外,还可以使用Executors类中提供的一些静态方法来创建线程池,例如newFixedThreadPool()、newCachedThreadPool()和newSingleThreadExecutor()等。这些方法都可以用于创建不同类型的线程池,例如固定大小的线程池、可缓存的线程池和单个线程的线程池等。
总之,线程池是一种非常重要的多线程并发处理技术,它可以提高程序的性能和可靠性。在实际应用中,我们可以根据实际需求选择不同类型的线程池来创建,并且可以根据需要进行调优和优化,以达到最优的效果。
【Java基础】线程池的原理是什么
什么是线程池?
总归为:池化技术 ---》数据库连接池 缓存架构 缓存池 线程池 内存池,连接池,这种思想演变成缓存架构技术---》 JDK设计思想有千丝万缕的联系
首先我们从最核心的ThreadPoolExecutor类中的方法讲起,然后再讲述它的实现原理,接着给出了它的使用示例,最后讨论了一下如何合理配置线程池的大小。
Java 中的 ThreadPoolExecutor 类
java.uitl.concurrent.ThreadPoolExecutor 类是线程池中最核心的一个类,因此如果要透彻地了解Java 中的线程池,必须先了解这个类。下面我们来看一下 ThreadPoolExecutor 类的具体实现源码。
在 ThreadPoolExecutor 类中提供了四个构造方法:
从上面的代码可以得知,ThreadPoolExecutor 继承了 AbstractExecutorService 类,并提供了四个构造器,事实上,通过观察每个构造器的源码具体实现,发现前面三个构造器都是调用的第四个构造器进行的初始化工作。
下面解释下一下构造器中各个参数的含义:
corePoolSize:核心池的大小,这个参数跟后面讲述的线程池的实现原理有非常大的关系。在创建了线程池后,默认情况下,线程池中并没有任何线程,而是等待有任务到来才创建线程去执行任务,除非调用了prestartAllCoreThreads() 或者 prestartCoreThread()方法,从这 2 个方法的名字就可以看出,是预创建线程的意思,即在没有任务到来之前就创建 corePoolSize 个线程或者一个线程。默认情况下,在创建了线程池后,线程池中的线程数为0,当有任务来之后,就会创建一个线程去执行任务,当线程池中的线程数目达到 corePoolSize 后,就会把到达的任务放到缓存队列当中;
maximumPoolSize:线程池最大线程数,这个参数也是一个非常重要的参数,它表示在线程池中最多能创建多少个线程;
keepAliveTime:表示线程没有任务执行时最多保持多久时间会终止。默认情况下,只有当线程池中的线程数大于 corePoolSize 时,keepAliveTime 才会起作用,直到线程池中的线程数不大于 corePoolSize,即当线程池中的线程数大于 corePoolSize 时,如果一个线程空闲的时间达到 keepAliveTime,则会终止,直到线程池中的线程数不超过 corePoolSize。但是如果调用了 allowCoreThreadTimeOut(boolean) 方法,在线程池中的线程数不大于 corePoolSize 时,keepAliveTime 参数也会起作用,直到线程池中的线程数为0;
unit:参数 keepAliveTime 的时间单位,有 7 种取值,在 TimeUnit 类中有 7 种静态属性:
workQueue:一个阻塞队列,用来存储等待执行的任务,这个参数的选择也很重要,会对线程池的运行过程产生重大影响,一般来说,这里的阻塞队列有以下几种选择:
ArrayBlockingQueue 和 PriorityBlockingQueue 使用较少,一般使用 LinkedBlockingQueue 和 Synchronous。线程池的排队策略与 BlockingQueue 有关。
threadFactory:线程工厂,主要用来创建线程;
handler:表示当拒绝处理任务时的策略,有以下四种取值:
具体参数的配置与线程池的关系将在下一节讲述。
从上面给出的 ThreadPoolExecutor 类的代码可以知道,ThreadPoolExecutor 继承了AbstractExecutorService,我们来看一下 AbstractExecutorService 的实现:
AbstractExecutorService 是一个抽象类,它实现了 ExecutorService 接口。
我们接着看 ExecutorService 接口的实现:
而 ExecutorService 又是继承了 Executor 接口,我们看一下 Executor 接口的实现:
Android线程池的使用
在Android中有主线程和子线程的区分。主线程又称为UI线程,主要是处理一些和界面相关的事情,而子线程主要是用于处理一些耗时比较大的一些任务,例如一些网络操作,IO请求等。如果在主线程中处理这些耗时的任务,则有可能会出现ANR现象(App直接卡死)。
线程池,从名字的表明含义上我们知道线程池就是包含线程的一个池子,它起到新建线程、管理线程、调度线程等作用。
既然Android中已经有了线程的概念,那么为什么需要使用线程池呢?我们从两个方面给出使用线程池的原因。
在Android中线程池就是ThreadPoolExecutor对象。我们先来看一下ThreadPoolExecutor的构造函数。
我们分别说一下当前的几个参数的含义:
第一个参数corePoolSize为 核心线程数 ,也就是说线程池中至少有这么多的线程,即使存在的这些线程没有执行任务。但是有一个例外就是,如果在线程池中设置了allowCoreThreadTimeOut为true,那么在 超时时间(keepAliveTime) 到达后核心线程也会被销毁。
第二个参数maximumPoolSize为 线程池中的最大线程数 。当活动线程数达到这个数后,后续添加的新任务会被阻塞。
第三个参数keepAliveTime为 线程的保活时间 ,就是说如果线程池中有多于核心线程数的线程,那么在线程没有任务的那一刻起开始计时,如果超过了keepAliveTime,还没有新的任务过来,则该线程就要被销毁。同时如果设置了allowCoreThreadTimeOut为true,该时间也就是上面第一条所说的 超时时间 。
第四个参数unit为 第三个参数的计时单位 ,有毫秒、秒等。
第五个参数workQueue为 线程池中的任务队列 ,该队列持有由execute方法传递过来的Runnable对象(Runnable对象就是一个任务)。这个任务队列的类型是BlockQueue类型,也就是阻塞队列,当队列的任务数为0时,取任务的操作会被阻塞;当队列的任务数满了(活动线程达到了最大线程数),添加操作就会阻塞。
第六个参数threadFactory为 线程工厂 ,当线程池需要创建一个新线程时,使用线程工厂来给线程池提供一个线程。
第七个参数handler为 拒绝策略 ,当线程池使用有界队列时(也就是第五个参数),如果队列满了,任务添加到线程池的时候的一个拒绝策略。
可以看到FixedThreadPool的构建调用了ThreadPoolExecutor的构造函数。从上面的调用中可以看出FixedThreadPool的几个特点:
可以看到CacheThreadPool的构建调用了ThreadPoolExecutor的构造函数。从上面的调用中可以看出CacheThreadPool的几个特点:
可以看到ScheduledThreadPoolExecutor的构建调用了ThreadPoolExecutor的构造函数。从上面的调用中可以看出ScheduledThreadPoolExecutor的几个特点:
可以看到SingleThreadExecutor的构建调用了ThreadPoolExecutor的构造函数。从上面的调用中可以看出SingleThreadExecutor的几个特点:
什么叫线程池线程池如何使用
1、什么是线程池: java.util.concurrent.Executors提供了一个 java.util.concurrent.Executor接口的实现用于创建线程池
多线程技术主要解决处理器单元内多个线程执行的问题,它可以显著减少处理器单元的闲置时间,增加处理器单元的吞吐能力。
假设一个服务器完成一项任务所需时间为:T1 创建线程时间,T2 在线程中执行任务的时间,T3 销毁线程时间。
如果:T1 + T3 远大于 T2,则可以采用线程池,以提高服务器性能。
一个线程池包括以下四个基本组成部分:
1、线程池管理器(ThreadPool):用于创建并管理线程池,包括 创建线程池,销毁线程池,添加新任务;
2、工作线程(PoolWorker):线程池中线程,在没有任务时处于等待状态,可以循环的执行任务;
3、任务接口(Task):每个任务必须实现的接口,以供工作线程调度任务的执行,它主要规定了任务的入口,任务执行完后的收尾工作,任务的执行状态等;
4、任务队列(taskQueue):用于存放没有处理的任务。提供一种缓冲机制。
线程池技术正是关注如何缩短或调整T1,T3时间的技术,从而提高服务器程序性能的。它把T1,T3分别安排在服务器程序的启动和结束的时间段或者一些空闲的时间段,这样在服务器程序处理客户请求时,不会有T1,T3的开销了。
线程池不仅调整T1,T3产生的时间段,而且它还显著减少了创建线程的数目,看一个例子:
假设一个服务器一天要处理50000个请求,并且每个请求需要一个单独的线程完成。在线程池中,线程数一般是固定的,所以产生线程总数不会超过线程池中线程的数目,而如果服务器不利用线程池来处理这些请求则线程总数为50000。一般线程池大小是远小于50000。所以利用线程池的服务器程序不会为了创建50000而在处理请求时浪费时间,从而提高效率。
线程与线程池
1、线程的状态。5个。
2、实现线程的方法,及其区别。2种:Runnable、Thread(+2种:Callable、FutureTask)。
3、start()和run()的区别。
4、Thread.sleep()和Thread.yield()区别
yield,音标 /jild/。线程的礼让,该线程退回到就绪状态(然后所有的就绪的线程凭借优先级抢资源)。
sleep,线程的阻塞(当阻塞时间结束,线程转入就绪状态)。
5、wait和sleep的区别
1)wait是object的方法,sleep是thread的静态方法;
2)wait需要在synchronized范围内使用,否则抛错 Exception in thread "main" java.lang.IllegalMonitorStateException ,而sleep则不需要;
3)wait是对象监听器的线程的等待,当该对象wait时,当前线程进入等待,其notify方法是随机唤起一个(等待该对象监听器的)线程;sleep是当前线程的沉睡,该线程的对象锁还是持有的;
4)wait出让系统资源,进入线程池中等待;sleep不会出让锁。二者都会让出CPU。
5、用户线程(user Thread)和守护线程(daemon Thread)的区别。
1)守护线程的区别在于thread.setDaemon(true),设置了就是守护线程,且必须在start()之前设置。
2)守护线程依赖于用户线程,没有用户线程,守护线程不存在。即当用户线程运行完毕,此时不管守护线程是否运行或运行完毕,立即停止。
6、线程调用的两种方式:
1)直接使用start()方法(在主方法中显式迭代调用或者构造方法中,便于外部隐式调用);
2)使用Executor来调用(CachedThreadPool()或者FixedThreadPool())。
两种方法的区别是:Executor执行线程都是隐式的。而且在构造方法中调用start()方法对于多线程是不安全的,而Executor则不会。
7、停止一个运行中线程的方法:
1)interrupt方法;
2)使用退出标志;
3)stop,但不建议(J8废除,原因是可能导致数据不一致)。
***隐藏网址***
6、Executor调用线程的两种方式的区别:
newCachedThreadPool()会为每一个任务都分配线程;
newFixedThreadPool(long)会限定可使用的线程数量,在前面的任务执行完之后,会将空线程分配给其他的任务。
7、在并发时,一个任务不能依赖于另一个任务,因为任务的关闭顺序无法保证。解决:1.依赖于非任务对象(volatile变量)来解决。2.锁。
8、锁的方式:2种,synchronize和Lock。区别在于Lock更加细粒度,比如锁的尝试获取,锁的锁定时间。
9、线程池的状态:5个。
1.running
2.shutdown
3.stop
4.tidying(当workQueue为0时,进入该状态)
5.terminated
10、shutdown和stop的区别。
二者都有线程池停止之意,且都不接收新线程了。但shutdown会处理掉已接收和正在执行的线程,而stop会中断所有的已接收和正在执行的线程。
11、threadPoolExecutor的参数含义。
corePoolSize:核心线程数。即最小存活线程数。
maximunPoolSize:最大线程数。
keepAliveTime:当线程数大于核心线程是,线程的存活时间。
unit:keepAliveTime的单位。
workQueue:工作队列。在线程执行前,线程会放在此处。
threadFactory:线程创建工厂(有一个默认工厂)。
handler:拒绝策略。当多余的线程请求时,执行的策略。默认是拒绝策略。
ps:关于workQueue:当需要使用一个线程时,会先看核心线程有无空闲线程,若有,则直接使用,没有,则创建并放在队列中等待被使用;当线程用完时,也会放在队列中,等待一会,实在没人用且已达到核心数时,会消亡该线程。
newSingleThreadExecutor() 和 newFixedThreadPool() 都是用的LinkedBlockingQueue队列,而 newCachedThreadPool() 用的是SynchronousQueue队列。
在 newSingleThreadExecutor() 中,如果前一个线程出异常了,那么我就执行下一个线程,不会出现停止,而其他的线程池会导致停止。
在 newFixedThreadPool() 中keepAliveTime是0,在 newCachedThreadPool() 中keepAliveTime是60s。
12、线程的循环调用(如每隔5秒调用线程):
这是一个初始化后延迟1秒,每隔5秒执行任务(秒单位共享)。
这是一个初始化后延迟1毫秒,每隔5秒执行任务。默认单位为毫秒。
参考: Java多线程线程池(4)--线程池的五种状态 。

更多文章:
vbnet连接sql数据库实例(请各位大侠给出用VB.NET连接oracle数据库并执行sql查询语句的代码示例,谢谢!!)
2026年7月21日 09:15
python编程实例详解(python函数变量及代码利用是什么python函数变量及代码利用说明)
2025年8月3日 06:00
已知大写字母a的ascii码值十进制(已知大写字母a的ASCII码值十进制表示为65那么asii码值为十进制数68的字母是)
2026年8月11日 21:30
struts2拦截器和过滤器的区别(struts2拦截器的作用是什么(它拦截什么)过滤器的作用是什么呢(过滤什么))
2025年6月18日 21:15
sql语句优化面试(面试问到 数据库性能优化 怎么回答 我是Oracle数据库)
2025年7月30日 02:15
commerce和commercial的区别(commercial名词)
2026年7月6日 01:00
shell脚本写加减乘除运算(用shell做个加减乘除运算)
2025年6月20日 21:30
keystone蝶阀中国代理(美国泰科TYCO阀门授权代理商)
2025年9月8日 02:45
日期型的函数datediff(datediff函数怎么用啊)
2025年12月17日 06:15
加拿大study permit(加拿大的STUDY PERMIT 里,签证官指定学校这句话什么意思 )
2026年8月7日 06:45
小米13发布会为何延期(小米和华为的冬季新品发布会为什么延期)
2026年6月3日 04:30
rank函数如何自动填充(excel根据最终得分列数据公式填充排名列数据)
2026年3月12日 12:15
rsync协议(为什么rsync服务对应的端口显示所属进程是xinetd而非rsync)
2025年11月11日 08:30
reset current branch to here(resetcurrentbranchtohere会覆盖本地代)
2025年11月13日 21:30
c语言中printf与scanf的先后顺序(c语言中printf 跟scanf执行顺序颠倒)
2026年2月26日 06:00
ASP.NET MVC 4框架揭秘:Controller类型的缓存?RxCache缓存框架
2026年6月1日 06:00
![vb 全局数组 如何在子过程里定义全局性的数组,在主函数里可以使用?在java中定义了一个二维数组,int[][] a = null;a[1] = new int[]{1,2,3};这样定义对不对](/static/images/nopic/15.jpg)










