线程池ThreadPool简单使用

 ThreadPoolExecutor可以用来创建线程池,例如:

1 ThreadPoolExecutor executor=new ThreadPoolExecutor(10,13,
2                 200,TimeUnit.MILLISECONDS,new ArrayBlockingQueue<Runnable>(5));
ThreadPoolExecutor 构造函数为:
public ThreadPoolExecutor(int corePoolSize,

                              int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) { this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, Executors.defaultThreadFactory(), defaultHandler); 
}

其中各参数的含义:

corePoolSize

线程池启动后,在池中保持的线程的最小数量。需要说明的是线程数量是逐步到达corePoolSize值的。例如corePoolSize被设置为10,而任务数量只有5,则线程池中最多会启动5个线程,而不是一次性地启动10个线程。

maxinumPoolSize

线程池中能容纳的最大线程数量,如果超出,则使用RejectedExecutionHandler拒绝策略处理。

keepAliveTime

线程的最大生命周期。这里的生命周期有两个约束条件:一:该参数针对的是超过corePoolSize数量的线程;二:处于非运行状态的线程。举个例子:如果corePoolSize(最小线程数)为10,maxinumPoolSize(最大线程数)为20,而此时线程池中有15个线程在运行,过了一段时间后,其中有3个线程处于等待状态的时间超过keepAliveTime指定的时间,则结束这3个线程,此时线程池中则还有12个线程正在运行。

unit

这是keepAliveTime的时间单位,可以是纳秒,毫秒,秒,分钟等。

workQueue

任务队列。当线程池中的线程都处于运行状态,而此时任务数量继续增加,则需要一个容器来容纳这些任务,这就是任务队列。这个任务队列是一个阻塞式的单端队列。

 

threadFactory

定义如何启动一个线程,可以设置线程的名称,并且可以确定是否是后台线程等。

handler

拒绝任务处理器。由于超出线程数量和队列容量而对继续增加的任务进行处理的程序。

《线程池ThreadPool简单使用》

《线程池ThreadPool简单使用》

 

具体实例:

 

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class ThreadPool {

	public static void main(String[] args) {
		//如果Executors提供的三个静态方法能满足要求,就尽量使用它提供的三个方法,因为自己去手动配置ThreadPoolExecutor的参数有点麻烦,要根据实际任务的类型和数量来进行配置
		ThreadPoolExecutor executor=new ThreadPoolExecutor(10,13,
				200,TimeUnit.MILLISECONDS,new ArrayBlockingQueue<Runnable>(5));
				for(int i=0;i<18;i++)
				{
				MyTask myTask=new MyTask(i);
				executor.execute(myTask);//提交线程
				System.out.println("线程池中的线程数目:"+executor.getPoolSize()+
				"队列中等待执行的任务数目:"+executor.getQueue().size()+
				"已经执行完的任务数目:"+executor.getCompletedTaskCount());
				}
				executor.shutdown();//启动有序关闭,
				}
}
		class MyTask implements Runnable {
			
				private int taskName;
				public MyTask(int num){
					this.taskName=num;
				}
				
				public void run(){
					System.out.println("正在执行:"+taskName);
					try
					{
					Thread.currentThread().sleep(4000);
					}
					catch(InterruptedException e)
					{
					e.printStackTrace();
					}
					System.out.println("task"+taskName+"执行完毕");
				}

		}

 

  不过在java doc中,并不提倡我们直接使用ThreadPoolExecutor,而是使用Executors类中提供的几个静态方法来创建线程池:

Executors.newCachedThreadPool();        
//创建一个缓冲池,缓冲池容量大小为Integer.MAX_VALUE
Executors.newSingleThreadExecutor();   
//创建容量为1的缓冲池
Executors.newFixedThreadPool(
int
);    
//创建固定容量大小的缓冲池

从它们的具体实现来看,它们实际上也是调用了ThreadPoolExecutor,只不过参数都已配置好了。

  newFixedThreadPool创建的线程池corePoolSize和maximumPoolSize值是相等的,它使用的LinkedBlockingQueue;

  newSingleThreadExecutor将corePoolSize和maximumPoolSize都设置为1,也使用的LinkedBlockingQueue;

  newCachedThreadPool将corePoolSize设置为0,将maximumPoolSize设置为Integer.MAX_VALUE,使用的SynchronousQueue,也就是说来了任务就创建线程运行,当线程空闲超过60秒,就销毁线程。

  实际中,如果Executors提供的三个静态方法能满足要求,就尽量使用它提供的三个方法,因为自己去手动配置ThreadPoolExecutor的参数有点麻烦,要根据实际任务的类型和数量来进行配置。

 

参考:https://www.cnblogs.com/dolphin0520/p/3932921.html

 

 

    原文作者:java 线程池
    原文地址: https://www.cnblogs.com/zhicheng-hu/p/9877684.html
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞