您现在的位置是:java学习笔记 >
java学习笔记
java 线程池如何实现多线程?
本 文 目 录
# <h2>Java线程池实现多线程</h2>
## 一、线程池的作用与主要运用的方法
在Java中,线程池是一种用于管理和控制多个并发线程的工具,其核心作用是减少线程创建和销毁开销、合理管理资源以及提供统一的并发执行框架。通过使用`java.util.concurrent`包下的ThreadPoolExecutor类,我们可以轻松地创建并配置一个线程池,从而高效地执行大量任务。
## 1. 创建线程池步骤:初始化配置
### 初始化线程池参数
- **核心线程数**:线程池中的常驻线程数量。
- **最大线程数**:线程池允许的最大线程数,超过这个数量的任务将排队等待。
- **线程存活时间**:非核心线程空闲时等待新任务的最长时间,超时则自动终止。
- **任务队列**:用于存放待处理任务的BlockingQueue。
```java
int corePoolSize = 5;
int maximumPoolSize = 10;
long keepAliveTime = 60L;
TimeUnit unit = TimeUnit.SECONDS;
BlockingQueue<Runnable> workQueue = new LinkedBlockingQueue<>();
ThreadFactory threadFactory = Executors.defaultThreadFactory();
RejectedExecutionHandler handler = new ThreadPoolExecutor.AbortPolicy();
ThreadPoolExecutor executor = new ThreadPoolExecutor(corePoolSize,
maximumPoolSize,
keepAliveTime,
unit,
workQueue,
threadFactory,
handler);
2. 提交任务至线程池步骤:execute方法
提交任务
通过调用线程池的execute(Runnable task)
方法提交任务到线程池中,由线程池根据当前线程状态选择从核心线程、非核心线程或任务队列中获取资源来执行该任务。
executor.execute(new Runnable() {
@Override
public void run() {
// 这里编写具体的任务逻辑
System.out.println("正在执行任务...");
}
});
3. 关闭线程池步骤:shutdown方法
关闭线程池
当所有任务执行完毕或者不再需要线程池时,可以调用shutdown()
或shutdownNow()
方法关闭线程池。前者会等待所有已提交任务完成后再停止,后者尝试取消未开始的任务并中断正在运行的任务。
executor.shutdown();
// 等待所有任务完成
while (!executor.isTerminated()) {
Thread.sleep(100);
}
System.out.println("所有任务已完成,线程池已关闭");
四、总结与注意事项
- 使用线程池能够有效地提高系统资源利用率,防止过多线程导致的系统资源耗尽问题。
- 根据实际应用场景合理设置线程池参数,如CPU核心数、任务特性(IO密集型或CPU密集型)等。
- 注意处理拒绝策略,当线程池和队列满载时,可通过自定义RejectedExecutionHandler进行特殊处理。
五、完整代码示例
import java.util.concurrent.*;
public class ThreadPoolExample {
public static void main(String[] args) {
int corePoolSize = 5;
int maximumPoolSize = 10;
long keepAliveTime = 60L;
TimeUnit unit = TimeUnit.SECONDS;
BlockingQueue<Runnable> workQueue = new LinkedBlockingQueue<>();
ThreadFactory threadFactory = Executors.defaultThreadFactory();
RejectedExecutionHandler handler = new ThreadPoolExecutor.AbortPolicy();
ThreadPoolExecutor executor = new ThreadPoolExecutor(corePoolSize,
maximumPoolSize,
keepAliveTime,
unit,
workQueue,
threadFactory,
handler);
for (int i = 0; i < 20; i++) {
final int taskId = i;
executor.execute(new Runnable() {
@Override
public void run() {
System.out.println("Task ID: " + taskId + " is running by " + Thread.currentThread().getName());
try {
Thread.sleep(1000); // 模拟任务执行时间
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
}
executor.shutdown();
while (!executor.isTerminated()) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("所有任务已完成,线程池已关闭");
}
}
- 上一篇
Java中解析XML的四种方法:DOM、SAX、StAX和JDOM
首先,Java中解析XML的方法主要有四种:DOM、SAX、StAX和JDOM。以下是一个简单的表格对比这几种方法:| 方法 | 描述 || --- | --- || DOM | 文档对象模型,将整个XML文档加载到内存中,形成一个树形结构,可以方便地进行增删改查操作 || SAX | 事件驱动的解析器,逐行读取XML文件,当遇到开始标签、结束标签等元素时触发事件 || StAX | 连续流式处理
- 下一篇
java中抽象类可以实现接口么
在Java编程语言中,抽象类和接口都是用于实现面向对象设计中的抽象概念的重要工具。其中,抽象类可以包含抽象方法(即没有具体实现的方法)以及具体方法,而接口则完全由抽象方法组成。更重要的是,抽象类不仅可以定义抽象方法,它还可以同时实现一个或多个接口,这样就能够在保持自身抽象特性的同时,继承接口的一系列行为约定。