首先,继承关系: Executor -> ExecutorService -> AbstractExecutorService -> ThreadPoolExecutor
Interface: Executor.execute(Runnable)
Interface: ExecutorService.submit(Callable) -- ExecutorService implements Executor
AbstractExecutorService实现了submit(Callable),这个需要调用execute(Runnable)来实现, 正是AbstractExecutorService的子类ThreadPoolExecutor中实现了execute(Runnable)
参数最全的构造方法
* @param corePoolSize the number of threads to keep in the pool, even
* if they are idle, unless {@code allowCoreThreadTimeOut} is set
* @param maximumPoolSize the maximum number of threads to allow in the
* pool
* @param keepAliveTime when the number of threads is greater than
* the core, this is the maximum time that excess idle threads
* will wait for new tasks before terminating.
* @param unit the time unit for the {@code keepAliveTime} argument
* @param workQueue the queue to use for holding tasks before they are
* executed. This queue will hold only the {@code Runnable}
* tasks submitted by the {@code execute} method.
* @param threadFactory the factory to use when the executor
* creates a new thread
* @param handler the handler to use when execution is blocked
* because the thread bounds and queue capacities are reached
public ThreadPoolExecutor(
int corePoolSize, //
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler)
JDK自带的配置好的线程池:
// 固定工作线程数量的线程池
ExecutorService executorService1 = Executors.newFixedThreadPool(3);
// 一个可缓存的线程池
ExecutorService executorService2 = Executors.newCachedThreadPool();
// 单线程化的Executor
ExecutorService executorService3 = Executors.newSingleThreadExecutor();
// 支持定时的以及周期性的任务执行
ExecutorService executorService4 = Executors.newScheduledThreadPool(3);
1.CachedThreadPool
CachedThreadPool首先会按照需要创建足够多的线程来执行任务(Task)。随着程序执行的过程,有的线程执行完了任务,可以被重新循环使用时,才不再创建新的线程来执行任务。我们采用《Thinking In Java》中的例子来分析。
首先,任务定义如下(实现了Runnable接口,并且复写了run方法):
package net.jerryblog.concurrent;
public class LiftOff implements Runnable{
protected int countDown = 10; //Default
private static int taskCount = 0;
private final int id = taskCount++;
public LiftOff() {}
public LiftOff(int countDown) {
this.countDown = countDown;
}
public String status() {
return "#" + id + "(" +
(countDown > 0 ? countDown : "LiftOff!") + ") ";
}
@Override
public void run() {
while(countDown-- > 0) {
System.out.print(status());
Thread.yield();
}
}
}
采用CachedThreadPool方式执行编写的客户端程序如下:
package net.jerryblog.concurrent;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class CachedThreadPool {
public static void main(String[] args) {
ExecutorService exec = Executors.newCachedThreadPool();
for(int i = 0; i < 10; i++) {
exec.execute(new LiftOff());
}
exec.shutdown();
}
}
上面的程序中,有10个任务,采用CachedThreadPool模式,exec没遇到一个LiftOff的对象(Task),就会创建一个线程来处理任务。现在假设遇到到第4个任务时,之前用于处理第一个任务的线程已经执行完成任务了,那么不会创建新的线程来处理任务,而是使用之前处理第一个任务的线程来处理这第4个任务。接着如果遇到第5个任务时,前面那些任务都还没有执行完,那么就会又新创建线程来执行第5个任务。否则,使用之前执行完任务的线程来处理新的任务。
2.FixedThreadPool
FixedThreadPool模式会使用一个优先固定数目的线程来处理若干数目的任务。规定数目的线程处理所有任务,一旦有线程处理完了任务就会被用来处理新的任务(如果有的话)。这种模式与上面的CachedThreadPool是不同的,CachedThreadPool模式下处理一定数量的任务的线程数目是不确定的。而FixedThreadPool模式下最多的线程数目是一定的。
采用FixedThreadPool模式编写客户端程序如下:
package net.jerryblog.concurrent;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class FixedThreadPool {
public static void main(String[] args) {
//三个线程来执行五个任务
ExecutorService exec = Executors.newFixedThreadPool(3);
for(int i = 0; i < 5; i++) {
exec.execute(new LiftOff());
}
exec.shutdown();
}
}
3.SingleThreadExecutor模式
SingleThreadExecutor模式只会创建一个线程。它和FixedThreadPool比较类似,不过线程数是一个。如果多个任务被提交给SingleThreadExecutor的话,那么这些任务会被保存在一个队列中,并且会按照任务提交的顺序,一个先执行完成再执行另外一个线程。
SingleThreadExecutor模式可以保证只有一个任务会被执行。这种特点可以被用来处理共享资源的问题而不需要考虑同步的问题。
SingleThreadExecutor模式编写的客户端程序如下:
package net.jerryblog.concurrent;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class SingleThreadExecutor {
public static void main(String[] args) {
ExecutorService exec = Executors.newSingleThreadExecutor();
for (int i = 0; i < 2; i++) {
exec.execute(new LiftOff());
}
}
}
分享到:
相关推荐
JDK自带线程池分析 JDK 自带线程池是 Java 语言中用于管理和执行线程的工具,旨在提高多线程编程的效率和灵活性。本文将详细介绍 JDK 自带线程池的组成、创建方法、优点和常见应用场景。 多线程技术 多线程技术是...
一、jdk自带线程池的类结构图 jdk自带的线程池主要是通过ThreadPoolExecutor类来实现的。ThreadPoolExecutor类是Executor框架中最核心的类,它提供了一个灵活的线程池管理机制,允许开发者根据需要创建不同类型的...
Java线程池是一种高效利用系统资源的机制,它允许开发者预先配置一定数量的线程,以便在...通过对JDK自带的`ThreadPoolExecutor`源码的学习,我们可以更深入地了解线程池的工作细节,以便更好地利用这一强大的工具。
JDK提供了一系列的线程池实现,包括`ThreadPoolExecutor`、`ScheduledThreadPoolExecutor`以及`Executors`工厂类。`ThreadPoolExecutor`是线程池的核心实现,它接受五个参数进行初始化: 1. `corePoolSize`: 核心...
线程池可以通过`ExecutorService`接口和`Executors`工厂类进行配置,如`ThreadPoolExecutor`,它可以限制并发线程的数量,处理任务队列溢出,以及支持取消和关闭操作。 - **异步任务调度(Asynchronous Task ...
RejectedExecutionHandler 的实现 JDK 自带的默认有 4 种: * AbortPolicy:丢弃任务,抛出运行时异常 * CallerRunsPolicy:由提交任务的线程来执行任务 * DiscardPolicy:丢弃这个任务,但是不抛异常 * ...
- 性能调优:通过JDK自带工具进行性能监控和调整。 这本教材覆盖了Java编程的基础到高级内容,通过实例和习题帮助读者巩固理论知识并提升实践能力,对于想要深入学习Java的开发者来说是一份宝贵的资源。通过阅读和...
9. **并发问题诊断和调试**:如何使用JDK自带的监控和诊断工具,如jstack、jconsole、VisualVM等来分析和解决并发问题。 10. **并发编程最佳实践**:书中可能会给出一些避免死锁、活锁、饥饿等问题的建议,以及如何...
9. **并发性能分析**:学习如何使用JDK自带的`jconsole`、`VisualVM`等工具来监控和分析并发程序的性能,找出瓶颈并进行优化。 10. **并发编程的最佳实践**:书中会总结一些并发编程的最佳实践,帮助你写出更安全、...
3. **性能监控与分析**:使用JDK自带的JConsole、VisualVM等工具,可以实时监控JVM的状态,包括CPU使用率、内存分配、线程状态等,以便定位性能瓶颈。 4. **JVM参数调整**:通过设置JVM启动参数,我们可以定制JVM的...
1. **JConsole**: JConsole是Java自带的可视化监控工具,它可以显示JVM的各种信息,包括线程的详细状态、CPU使用率等。通过JMX(Java Management Extensions)接口,开发者可以远程监控应用的线程情况。 2. **...
4. **原子操作与CAS**:Atomic类提供了一种无锁编程的手段,通过使用CAS(Compare and Swap)操作实现原子性的更新,从而避免了线程同步的开销。例如AtomicInteger、AtomicLong等,它们在高并发环境下性能优越。 5....
- **线程池**:讲解ExecutorService、ThreadPoolExecutor、ScheduledExecutorService的使用和配置,以及线程池的优化策略。 5. **并发异常处理** - **线程中断**:讨论中断机制,如何优雅地停止线程。 - **死锁*...
10. **性能调优与监控**:最后,书中可能会涵盖如何分析和优化并发程序的性能,以及如何使用JDK自带的监控工具(如`jconsole`、`VisualVM`等)进行线程监控和诊断。 通过阅读《Java并发编程的艺术》,开发者不仅能...
4. **线程池**:Java的`ExecutorService`和`ThreadPoolExecutor`允许我们管理和控制线程的创建和执行,有效避免了过度创建线程导致的性能问题。线程池的配置和管理是优化并发程序性能的关键环节。 5. **并发工具类*...
2. **线程池**:ExecutorService、ThreadPoolExecutor和ScheduledExecutorService的使用和优化。 通过理解和掌握这些知识点,开发者可以更好地理解Java程序的运行机制,解决性能问题,以及在面试中展现出对JVM的...
Java 是一种广泛使用的编程语言,尤其在企业级应用和服务器端开发中占据主导地位。面试时,面试官通常会从多个方面考察候选人的Java技能,包括基础、容器、多线程、反射、对象拷贝、Java Web、异常处理、网络编程、...
- JVisualVM(JDK自带)提供丰富的线程监控视图,包括线程状态、CPU占用、线程 dump等功能。 - VisualVM、YourKit等商业Java性能分析工具提供了更强大的线程分析能力。 10. **中断与异常处理** - `Thread....
- 如何使用JDK自带的jmap、jhat、jstack等命令行工具进行问题诊断。 7. **编译与执行** - JIT(Just-In-Time)编译器的作用,如何提高代码运行速度。 - 了解HotSpot虚拟机的即时编译策略,如C1和C2编译器。 - ...
4. **性能监控与分析**:使用JDK自带的JConsole、VisualVM或第三方工具如YourKit、JProfiler等,可以实时监控CPU、内存、线程和方法耗时,帮助定位性能瓶颈。 5. **代码优化**:编写高效的代码是基础,比如避免过度...