您当前的位置:首页 > 互联网教程

java 如何获得线程池中正在执行的线程数

发布时间:2025-05-20 21:46:54    发布人:远客网络

java 如何获得线程池中正在执行的线程数

一、java 如何获得线程池中正在执行的线程数

1、java中线程池的监控可以检测到正在执行的线程数。

2、通过线程池提供的参数进行监控。线程池里有一些属性在监控线程池的时候可以使用

3、taskCount:线程池需要执行的任务数量。

4、completedTaskCount:线程池在运行过程中已完成的任务数量。小于或等于taskCount。

5、largestPoolSize:线程池曾经创建过的最大线程数量。通过这个数据可以知道线程池是否满过。如等于线程池的最大大小,则表示线程池曾经满了。

6、getPoolSize:线程池的线程数量。如果线程池不销毁的话,池里的线程不会自动销毁,所以这个大小只增不+ getActiveCount:获取活动的线程数。

7、通过扩展线程池进行监控。通过继承线程池并重写线程池的beforeExecute,afterExecute和terminated方法,我们可以在任务执行前,执行后和线程池关闭前干一些事情。如监控任务的平均执行时间,最大执行时间和最小执行时间等。这几个方法在线程池里是空方法。如:

8、protected void beforeExecute(Thread t, Runnable r){}

二、什么是java线程池

1、多线程是为了能够让计算机资源合理的分配,对于处理不同的任务创建不同的线程进行处理,但是计算机创建一个线程或者销毁一个线程所花费的也是比较昂贵的,有时候需要同时处理的事情比较多,就需要我们频繁的进行线程的创建和销毁,这样花费的时间也是比较多的。为了解决这一问题,我们就可以引用线程池的概念。

2、所谓线程池就是将线程集中管理起来,当需要线程的时候,可以从线程池中获取空闲的线程,这样可以减少线程的频繁创建与销毁,节省很大的时间和减少很多不必要的操作。

3、在java中提供了ThreadPoolExecutor类来进行线程的管理,这个类继承于AbstractExecutorService,而AbstractExecutorService实现了ExecutorService接口,我们可以使用ThreadPoolExecutor来进行线程池的创建。

4、在ThreadPoolExecutor的构造方法中,有多个参数,可以配置不同的参数来进行优化。这个类的源码构造方法为:

5、public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler)其中每个参数代表的意义分别为

6、corePoolSize:线程池中的核心线程数量,当线程池中当前的线程数小于这个配置的时候,如果有一个新的任务到来,即使线程池中还存在空闲状态的线程,程序也会继续创建一个新的线程放进线程池当中

7、maximumPoolSize:线程池中的线程最大数量

8、keepAliveTime:当线程池中的线程数量大于配置的核心线程数量(corePoolSize)的时候,如果当前有空闲的线程,则当这个空闲线程可以存在的时间,如果在keepAliveTime这个时间点内没有新的任务使用这个线程,那么这个线程将会结束,核心线程不会结束,但是如果配置了allowCoreThreadTimeOut= true,则当空闲时间超过keepAliveTime之后,线程也会被结束调,默认allowCoreThreadTimeOut= false,即表示默认情况下,核心线程会一直存在于线程池当中。

9、unit:空闲线程保持连接时间(keepAliveTime)的时间单位

10、workQueue:阻塞的任务队列,用来保存等待需要执行的任务。

11、threadFactory:线程工厂,可以根据自己的需求去创建线程的对象,设置线程的名称,优先级等属性信息。

12、handler:当线程池中存在的线程数超过设置的最大值之后,新的任务就会被拒绝,可以自己定义一个拒绝的策略,当新任务被拒绝之后,就会使用hander方法进行处理。

13、在java中也提供了Executors工具类,在这个工具类中提供了多个创建线程池的静态方法,其中包含newCachedThreadPool、newFixedThreadPool、newScheduledThreadPool、newSingleThreadExecutor等。但是他们每个方法都是创建了ThreadPoolExecutor对象,不同的是,每个对象的初始参数值不一样;

三、java线程池怎么实现的

线程池简介:

多线程技术主要解决处理器单元内多个线程执行的问题,它可以显著减少处理器单元的闲置时间,增加处理器单元的吞吐能力。

多线程技术主要解决处理器单元内多个线程执行的问题,它可以显著减少处理器单元的闲置时间,增加处理器单元的吞吐能力。

假设一个服务器完成一项任务所需时间为: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而在处理请求时浪费时间,从而提高效率。

代码实现中并没有实现任务接口,而是把Runnable对象加入到线程池管理器(ThreadPool),然后剩下的事情就由线程池管理器(ThreadPool)来完成了

*线程池类,线程管理器:创建线程,执行任务,销毁线程,获取线程基本信息

privateWorkThread[]workThrads;

privatestaticvolatileintfinished_task=0;

//任务队列,作为一个缓冲,List线程不安全

privateList<Runnable>taskQueue=newLinkedList<Runnable>();

privatestaticThreadPoolthreadPool;

//创建具有默认线程个数的线程池

//创建线程池,worker_num为线程池中工作线程的个数

privateThreadPool(intworker_num){

ThreadPool.worker_num=worker_num;

workThrads=newWorkThread[worker_num];

for(inti=0;i<worker_num;i++){

workThrads[i]=newWorkThread();

workThrads[i].start();//开启线程池中的线程

//单态模式,获得一个默认线程个数的线程池

publicstaticThreadPoolgetThreadPool(){

returngetThreadPool(ThreadPool.worker_num);

//单态模式,获得一个指定线程个数的线程池,worker_num(>0)为线程池中工作线程的个数

//worker_num<=0创建默认的工作线程个数

publicstaticThreadPoolgetThreadPool(intworker_num1){

worker_num1=ThreadPool.worker_num;

threadPool=newThreadPool(worker_num1);

//执行任务,其实只是把任务加入任务队列,什么时候执行有线程池管理器觉定

publicvoidexecute(Runnabletask){

//批量执行任务,其实只是把任务加入任务队列,什么时候执行有线程池管理器觉定

publicvoidexecute(Runnable[]task){

//批量执行任务,其实只是把任务加入任务队列,什么时候执行有线程池管理器觉定

publicvoidexecute(List<Runnable>task){

//销毁线程池,该方法保证在所有任务都完成的情况下才销毁所有线程,否则等待任务完成才销毁

while(!taskQueue.isEmpty()){//如果还有任务没执行完成,就先睡会吧

}catch(InterruptedExceptione){

//工作线程停止工作,且置为null

for(inti=0;i<worker_num;i++){

taskQueue.clear();//清空任务队列

publicintgetWorkThreadNumber(){

//返回已完成任务的个数,这里的已完成是只出了任务队列的任务个数,可能该任务并没有实际执行完成

publicintgetFinishedTasknumber(){

//返回任务队列的长度,即还没处理的任务个数

//覆盖toString方法,返回线程池信息:工作线程个数和已完成任务个数

return"WorkThreadnumber:"+worker_num+"finishedtasknumber:"

+finished_task+"waittasknumber:"+getWaitTasknumber();

privateclassWorkThreadextendsThread{

//该工作线程是否有效,用于结束该工作线程

*关键所在啊,如果任务队列不空,则取出任务执行,若任务队列空,则等待

while(isRunning){//注意,若线程无效则自然结束run方法,该线程就没用了

while(isRunning&&taskQueue.isEmpty()){//队列为空

}catch(InterruptedExceptione){

r=taskQueue.remove(0);//取出任务

//停止工作,让该线程自然执行完run方法,自然结束