一、线程池的创建
我们可以通过ThreadPoolExecutor来创建一个线程池。
ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue)
- corePoolSize(线程池的基本大小):当提交一个任务到线程池时,线程池会创建一个线程来执行任务,即使其他空闲的基本线程能够执行新任务也会创建线程,等到需要执行的任务数大于线程池基本大小时就不再创建(这时新加入的任务将会放在任务队列中,如果队列满了,线程个数还没有超过最大数,则才会再创建线程)。如果调用了线程池的prestartAllCoreThreads方法,线程池会提前创建并启动所有基本线程。
- workQueue(任务队列):用于保存等待执行的任务的阻塞队列。 可以选择以下几个阻塞队列。
- ArrayBlockingQueue:是一个基于数组结构的有界阻塞队列,此队列按 FIFO(先进先出)原则对元素进行排序。
- LinkedBlockingQueue:一个基于链表结构的阻塞队列,此队列按FIFO (先进先出) 排序元素,吞吐量通常要高于ArrayBlockingQueue。静态工厂方法Executors.newFixedThreadPool()使用了这个队列。
- SynchronousQueue:一个不存储元素的阻塞队列。每个插入操作必须等到另一个线程调用移除操作,否则插入操作一直处于阻塞状态,吞吐量通常要高于LinkedBlockingQueue,静态工厂方法Executors.newCachedThreadPool使用了这个队列。
- PriorityBlockingQueue:一个具有优先级的无限阻塞队列。
- maximumPoolSize(线程池最大大小):线程池允许创建的最大线程数。如果队列满了,并且已创建的线程数小于最大线程数,则线程池会再创建新的线程执行任务。值得注意的是如果使用了无界的任务队列这个参数就没什么效果。
- ThreadFactory:用于设置创建线程的工厂,可以通过线程工厂给每个创建出来的线程设置更有意义的名字。
- RejectedExecutionHandler(饱和策略):当队列和线程池都满了,说明线程池处于饱和状态,那么必须采取一种策略处理提交的新任务。这个策略默认情况下是AbortPolicy,表示无法处理新任务时抛出异常。以下是JDK1.5提供的四种策略。
- AbortPolicy:直接抛出异常。
- CallerRunsPolicy:只用调用者所在线程来运行任务。
- DiscardOldestPolicy:丢弃队列里最先进去的一个任务,并执行当前任务。
- DiscardPolicy:不处理,丢弃掉。
- 当然也可以根据应用场景需要来实现RejectedExecutionHandler接口自定义策略。如记录日志或持久化不能处理的任务。
- keepAliveTime(线程活动保持时间):线程池的工作线程空闲后,保持存活的时间。所以如果任务很多,并且每个任务执行的时间比较短,可以调大这个时间,提高线程的利用率。
- TimeUnit(线程活动保持时间的单位):可选的单位有天(DAYS),小时(HOURS),分钟(MINUTES),毫秒(MILLISECONDS),微秒(MICROSECONDS, 千分之一毫秒)和毫微秒(NANOSECONDS, 千分之一微秒)。
二、Executors提供了一些方便创建ThreadPoolExecutor的常用方法,主要有以下几个:
1、 Executors.newFixedThreadPool(int nThreads);
说明:创建固定大小(nThreads, 大小不能超过int的最大值)的线程池
// 线程数量 int nThreads = 20;
// 创建executor 服务 : ExecutorService executor = Executors.newFixedThreadPool(nThreads) ;
重载后的版本,需要传入实现了ThreadFactory接口的对象。
ExecutorService executor = Executors. newFixedThreadPool(nThreads, threadFactory);
说明:创建固定大小(nThreads, 大小不能超过int的最大值) 的线程池,缓冲任务的队列为LinkedBlockingQueue,大小为整型的最大数,当使用此线程池时,在同执行的任务数量超过传入的线程池大小值后,将会放入LinkedBlockingQueue,在LinkedBlockingQueue中的任务需要等待线程空闲后再执行,如果放入LinkedBlockingQueue中的任务超过整型的最大数 时,抛出RejectedExecutionException。
2、Executors.newSingleThreadExecutor():创建大小为1的固定线程池。
ExecutorService executor = Executors.newSingleThreadExecutor();
重载后的版本,需要多传入实现了ThreadFactory接口的对象。
ExecutorService executor = Executors. newSingleThreadScheduledExecutor(ThreadFactory threadFactory)
说明:创建大小为1的固定线程池,执行任务的线程只有一个,其它的(任务)task都放在LinkedBlockingQueue中排队等待执行。
3、Executors.newCachedThreadPool();创建corePoolSize为0,最大线程数为整型的最大数,线程 keepAliveTime为1分钟,缓存任务的队列为SynchronousQueue的线程池。
ExecutorService executor = Executors.newCachedThreadPool();
当然也可以以下面的方式创建,重载后的版本,需要多传入实现了ThreadFactory接口的对象。
ExecutorService executor = Executors.newCachedThreadPool(ThreadFactory threadFactory) ;
说明:使用时,放入线程池的task任务会复用线程或启动新线程来执行,注意事项:启动的线程数如果超过整型最大值后会抛出RejectedExecutionException异常,启动后的线程存活时间为一分钟。
4、Executors.newScheduledThreadPool(int corePoolSize):创建corePoolSize大小的线程池。
// 线程数量 int corePoolSize= 20;
// 创建executor 服务 : ExecutorService executor = Executors.newScheduledThreadPool(corePoolSize) ;
重载后的版本,需要多传入实现了ThreadFactory接口的对象。
ExecutorService executor = Executors.newScheduledThreadPool(corePoolSize, threadFactory) ;
说明:线程keepAliveTime为0,缓存任务的队列为DelayedWorkQueue,注意不要超过整型的最大值。
相关推荐
`ExecutorService`的实例通常通过`Executors`工厂类来创建。在示例中,使用`Executors.newFixedThreadPool(int nThreads)`创建了一个固定大小的线程池,参数`nThreads`定义了线程池中允许的最大线程数。在这个例子...
1. **创建ExecutorService实例**:根据需求选择合适的构造方法创建线程池。 2. **提交任务**:使用`execute(Runnable task)`方法提交Runnable任务,或者使用`submit(Callable<T> task)`提交Callable任务并获取Future...
ExecutorService service = Executors.newCachedThreadPool(); ``` 2. 定长线程池:定长线程池是Java中的另一个常用的线程池,它的大小是固定的,可以指定线程池的大小。 ```java ExecutorService service = ...
本篇将深入探讨标题"8种常用创建线程的方法thread.zip"中提到的八种主要的Java线程创建方法,帮助开发者更好地理解和掌握这一核心概念。 1. 继承Thread类 Java中的`Thread`类是所有线程的基类,我们可以通过创建`...
##### 创建ExecutorService `java.util.concurrent.Executors`类提供了一系列静态方法用于创建不同类型的`ExecutorService`: - **newCachedThreadPool**:创建一个可根据需要创建新线程的线程池。如果线程池长度...
`ExecutorService`可以通过`Executors`工具类的静态方法创建,提供了多种类型的线程池: - `newCachedThreadPool()`:创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建...
这里使用了`Executors`工具类中的`newFixedThreadPool`方法创建了一个固定大小的线程池,然后使用`execute`方法在线程池中执行`Windows_Thread`类的实例。 #### 监听器与事件处理 在Swing中,可以通过添加监听器来...
Executors 工厂类提供了一系列静态方法来创建不同类型的 ExecutorService 实例。在这个例子中,我们使用 Executors.newFixedThreadPool 创建了一个固定大小的线程池,它会维护指定数量的线程来执行任务。这有助于...
本文将深入探讨Java中线程池的常用实现,主要基于Java的`java.util.concurrent`包下的`ExecutorService`接口及其实现,包括`ThreadPoolExecutor`、`Executors`提供的几种静态工厂方法创建的线程池,以及`ForkJoin...
`ExecutorService`接口定义了线程池的核心功能,而`Executors`类则提供了一些常用的线程池实现。 通过上述方法和工具,开发者可以在Java中有效地创建和管理线程,以实现复杂的并发执行逻辑,提高程序的性能和响应...
`ExecutorService`接口提供了以下常用方法: - `execute(Runnable command)`:提交一个Runnable任务到线程池,线程池会尽可能快地执行。 - `submit(Runnable task)`:和`execute()`类似,但submit()方法返回一个...
这是更常用的一种方式,它允许你创建一个实现了 `Runnable` 接口的类,然后在 `Thread` 类中传入该对象并调用 `start` 方法。这种方式的好处在于,由于 `Runnable` 是一个接口,你可以实现多个接口,解决了单继承的...
- 常用的实现类有`ThreadPoolExecutor`,可以通过`Executors`静态工厂方法创建线程池,如`newFixedThreadPool`创建固定大小的线程池。 - 使用`submit()`提交任务,`shutdown()`关闭线程池,`Future`接口用于获取...
Java中创建线程池的主要工具类是`java.util.concurrent.ExecutorService`,它提供了一种标准的方式创建不同类型的线程池。常用的线程池实现包括: 1. **FixedThreadPool**:创建固定大小的线程池,可以复用指定数量...
Executors 是 Java 中的一个工具类,提供了一些常用的线程池实现。然而,这些实现都有其缺陷,例如 FixedThreadPool 和 SingleThreadPool 的请求队列长度可以达到 Integer.MAX_VALUE,可能会导致 OOM。因此,不建议...
- **线程池**:ExecutorService、ThreadPoolExecutor和Executors的理解与使用。 5. **异常处理** - **异常分类**:检查异常和运行时异常的区别。 - **try-catch-finally**:异常的捕获、处理和资源释放。 - **...
在上面的示例中,`main`方法创建了一个单线程池,所有的任务都会在同一个线程中按顺序执行。 2. **可缓存线程池**:`Executors.newCachedThreadPool()` 创建的线程池会尽可能重用已存在的线程,如果没有可用线程,...
1. 创建线程池:使用`Executors`静态工厂方法创建一个固定大小的线程池,如`ExecutorService executor = Executors.newFixedThreadPool(poolSize);` 2. 实现图片下载接口:定义一个接口,包含下载图片的方法,如`...