创建线程池的几种方式
创建线程池是多线程编程中的一个常见需求。在Java中,使用线程池可以避免在高并发情况下频繁地创建和销毁线程,提高系统性能和稳定性。Java中创建线程池的几种方式如下:
- 使用
ThreadPoolExecutor
类手动创建线程池; - 使用
Executors
类提供的静态方法创建线程池; - 使用Spring框架提供的线程池。
创建线程池的四种方式
- 在
ThreadPoolExecutor
构造方法中传入必要参数。这种方式可以灵活地配置线程池,如指定核心线程数、最大线程数、线程的空闲时间等参数。ThreadPoolExecutor threadPool = new ThreadPoolExecutor(coreSize, maxSize, keepAliveTime, TimeUnit.SECONDS, workQueue);
- 使用
Executors
工具类中提供的静态方法创建线程池。Executors
类中提供了多个静态方法,可以根据需要选择。ExecutorService threadPool = Executors.newFixedThreadPool(2);
- 创建
ScheduledExecutorService
线程池,可用于定时或周期性执行任务。ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(2);
- 创建支持单个线程的线程池,这是一种特殊的线程池。
ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();
创建线程池的七种方式
newCachedThreadPool()
方法创建一个缓存线程池,它可以根据需求创建新线程,但在不被使用时则会回收旧线程。ExecutorService threadPool = Executors.newCachedThreadPool();
newFixedThreadPool()
方法创建一个固定大小的线程池,该线程池中的线程数始终保持不变。ExecutorService threadPool = Executors.newFixedThreadPool(5);
newSingleThreadExecutor()
方法创建一个只有一个线程的线程池,该线程池保证任何时候都只有一个线程在执行。ExecutorService threadPool = Executors.newSingleThreadExecutor();
newSingleThreadScheduledExecutor()
方法创建一个只有一个线程的支持定时执行的线程池。ScheduledExecutorService scheduledThreadPool = Executors.newSingleThreadScheduledExecutor();
newScheduledThreadPool()
方法创建一个支持定时执行的线程池。ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5);
newWorkStealingPool()
方法创建一个具有工作窃取算法的线程池,可以有效地利用多核CPU的性能。ExecutorService threadPool = Executors.newWorkStealingPool();
ForkJoinPool
类创建一个ForkJoinPool
线程池,该线程池主要用于解决分治任务。ForkJoinPool forkJoinPool = new ForkJoinPool();
创建线程池的七个参数
corePoolSize
:线程池中的常驻线程数。maximumPoolSize
:线程池中允许的最大线程数。keepAliveTime
:线程池中的空闲线程的存活时间。unit
:用于指定keepAliveTime
的时间单位。workQueue
:任务等待队列。threadFactory
:线程工厂,用于创建新线程。handler
:拒绝策略,用于处理超出线程池容量时的任务处理方式。
创建线程池参数
corePoolSize
和maximumPoolSize
参数的设置。 如果线程池中的线程数少于corePoolSize
时,无论有多少任务需要执行,线程池都会创建新线程来处理。当线程池中的线程数已经达到corePoolSize
时,新任务会被提交到等待队列中,直到有空闲线程可以处理为止。如果等待队列已满并且池中线程数量还没有达到maximumPoolSize
,则继续创建新的线程处理任务。如果池中线程数量已经达到maximumPoolSize
,拒绝策略便会生效。keepAliveTime
参数的设置。keepAliveTime
指定了非核心线程的空闲时间,这些线程会在空闲时间超过这个值时被回收。其单位由unit
参数指定。如果把keepAliveTime
设置为0或者小于0,则非核心线程会立即被回收。workQueue
参数的设置。workQueue
指定了等待队列,可选的队列类型包括SynchronousQueue
、LinkedTransferQueue
、ArrayBlockingQueue
、PriorityBlockingQueue
等。对于使用SynchronousQueue
队列和maximumPoolSize=1
的线程池,可以使得任务不会在队列中等待,而是直接交给核心线程执行,避免任务执行的延迟。使用ArrayBlockingQueue
等有界队列时,任务进入队列后,如果线程池中线程数量已经达到corePoolSize
时,新任务会在等待队列中等待一段时间,直到有空闲线程可以处理为止。
创建线程池的方法
- 使用
ThreadPoolExecutor
类创建线程池。ThreadPoolExecutor threadPool = new ThreadPoolExecutor(coreSize, maxSize, keepAliveTime, TimeUnit.SECONDS, workQueue);
- 使用
Executors
类提供的静态方法创建线程池。ExecutorService threadPool = Executors.newFixedThreadPool(2);
创建线程池四种方法
- 在
ThreadPoolExecutor
构造方法中传入必要参数:ThreadPoolExecutor threadPool = new ThreadPoolExecutor(coreSize, maxSize, keepAliveTime, TimeUnit.SECONDS, workQueue);
- 使用
Executors
工具类中提供的静态方法创建线程池:ExecutorService threadPool = Executors.newFixedThreadPool(2);
- 创建
ScheduledExecutorService
线程池,可用于定时或周期性执行任务:ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(2);
- 创建支持单个线程的线程池:
ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();
创建线程池进行操作
- 使用
submit()
方法将Callable
或Runnable
任务提交给线程池。Future<?> future = threadPool.submit(callable);
- 使用
execute()
方法将Runnable
任务提交给线程池。threadPool.execute(runnable);
- 使用
invokeAll()
方法批量提交Callable
任务并返回结果。List<Future<String>> futures = threadPool.invokeAll(callableTasks);
- 使用
invokeAny()
方法提交多个Callable
任务并返回其中任意一个任务的结果。String result = threadPool.invokeAny(callableTasks);
创建线程池构造方法
ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue)
:最基本的构造方法,通过指定corePoolSize
、maximumPoolSize
、keepAliveTime
、unit
和workQueue
来创建一个线程池。ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory)
:指定线程池中线程的创建工厂。ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, RejectedExecutionHandler handler)
:指定线程池中超出线程容量时的拒绝策略。ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler)
:同时指定线程的创建工厂和拒绝策略。
小结
本文从多个方面详细介绍了Java中创建线程池的方式和参数,对于想要使用线程池改善程序性能和稳定性的开发者有一定的参考帮助。但是需要注意的是,对于线程池的使用需要根据具体需求进行细致的分析和调整,以保证程序的性能和效率。