Java线程池
线程池是java重要的一部分,在开发过程中有着极其重要的作用。控制线程池中线程的个数也是极其重要的。本文分享一下我在学习过程中所掌握的三种控制线程数量的方法
一般我们会用synchronized来实现,但是这样同一时刻就只能一个线程处于方法或者同步块中。如果我们想让任意几个线程处于线程池中我们可以使用Semaphore、Executor或者ThreadPoolExecytor来实现。
1、Semaphore实现方法:
首先我们初始化一个Semaphore对象
Semaphore semaphore = new Semaphore(5)
;//即为我们允许的同时存在的线程的个数,当我们开启一个线程时,我们可以使用semaphore.acquire();方法来获取一把锁,当锁全部用完后如果有新的线程要进来那么就会进入阻塞状态。当线程池里边的某个线程运行完之后执行semaphore.release();方法,释放出来一把锁,此时阻塞的线程就能够获取到这把锁进入运行状态,
通过设置semaphore的参数我们就能很简单的控制允许的线程数量。
2、Executor实现方法:
首先仍要初始化Executor对象
Executor executor = Executors.newCachedThreadPool();//缓存线程池
Executor executor2 = Executors.newFixedThreadPool(5);//固定个数线程池,个数为5
Executor executor3 = Executors.newSingleThreadExecutor();//单个线程
Executor executor4 = Executors.newScheduledThreadPool(5);//计划任务线程池
一般使用的是FixedThreadPool,
当我们需要开始一个线程时使用execute方法这样当我们开启超过五个线程时,线程会进入阻塞状态,
executor2.execute(new Runnable() {
@Override
public void run() {
}
});
3、ThreadPoolExecytor实现方法:
首先仍然是初始化一个ThreadPoolExecutor对象,
在创建这个对象的时候我们需要去理解这个构造函数里边每一个参数的意思
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory, handler)
第一个参数corePoolSize:核心线程池的大小,也就是系统平时保留的线程的数量
第二个参数maximumPoolSize:最多线程数量
第三个参数 keepAliveTime:线程最大空闲时间,超出corePoolSize的线程最大的保留时间
第四个参数 unit:时间单位
第五个参数workQueue:线程等待队列(一般是LinkedBlockingDeque和ArrayBlockingQueue,第一个为队列,第二个为数组,队列方便增删,数组方便查询)
第六个参数 threadFactory:线程工厂,用于创建线程
第七个参数 handler:饱和策略,就是当线程等待队列和最大线程数量都满了之后如果有新的线程创建采取的措施。
当我们要开始一个线程的时候只需执行threadPoolExecutor对象的execute方法就会执行线程。
当系统开始创建线程的时候会首先放在corePoolSize里边,当corePoolSize满了之后如果有新的线程创建,那么这些线程会进入阻塞队列中,当阻塞队列满了之后仍然后有线程创建那么就会启动新的线程,如果阻塞队列和最大线程数都满了仍然后新的线程创建就会启动饱和策略。