java Thread pool

本文展示了一个使用Java创建固定大小线程池的例子,并演示了如何通过调用awaitTermination方法来等待所有任务完成。

pool.awaitTermination(1, TimeUnit.SECONDS); //可以和pool.shutdownNow();配合使用




public class MyThread extends Thread {

@Override

public void run() {

System.out.println(Thread.currentThread().getId() + ":" + Thread.currentThread().getName() + "正在执行。。。");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

}




import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

public class TestFixedThreadPool {

public static void main(String[] args) {

// 创建一个可重用固定线程数的线程池

ExecutorService pool = Executors.newFixedThreadPool(2);

// 创建实现了Runnable接口对象,Thread对象当然也实现了Runnable接口

Thread t1 = new MyThread();

Thread t2 = new MyThread();

Thread t3 = new MyThread();

Thread t4 = new MyThread();

Thread t5 = new MyThread();

// 将线程放入池中进行执行

pool.execute(t1);

pool.execute(t2);

pool.execute(t3);

pool.execute(t4);

pool.execute(t5);

// 关闭线程池
pool.shutdown();

System.out.println("pool.isTerminated():" + pool.isTerminated());

try {
pool.awaitTermination(1000, TimeUnit.SECONDS);
} catch (InterruptedException e) {
e.printStackTrace();
}

System.out.println("pool.isTerminated():" + pool.isTerminated());

// while(!pool.isTerminated()) {
// System.out.println("wait");
// try {
// Thread.sleep(3000);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
// }

System.out.println("finished");
}

}
Java中,“pool exhausted”通常表示资源池(如线程池、数据库连接池等)中的所有资源已被占用,无法为新的请求分配资源。这种情况常见于并发场景下,当池的最大容量不足以处理突发请求时,就会抛出资源耗尽的异常或导致请求阻塞。 ### 常见场景及示例 #### 1. **线程池耗尽** 当使用`ExecutorService`(如`ThreadPoolExecutor`)时,如果核心线程数、最大线程数和任务队列配置不合理,可能导致线程池资源耗尽。 ```java import java.util.concurrent.*; public class ThreadPoolExhaustedExample { public static void main(String[] args) { // 创建固定大小为2的线程池 ExecutorService executor = Executors.newFixedThreadPool(2); // 提交5个任务(线程池无法同时处理) for (int i = 0; i < 5; i++) { final int taskId = i; try { executor.submit(() -> { try { Thread.sleep(2000); // 模拟耗时任务 } catch (InterruptedException e) { Thread.currentThread().interrupt(); } System.out.println("Task " + taskId + " completed"); }); } catch (RejectedExecutionException e) { System.err.println("Task " + taskId + " rejected: Thread pool exhausted"); } } executor.shutdown(); } } ``` **输出**: 前2个任务会正常执行,后续任务会因线程池耗尽被拒绝(抛出`RejectedExecutionException`)。 #### 2. **数据库连接池耗尽** 使用HikariCP等连接池时,如果连接数配置过小或未及时释放连接,可能导致连接池耗尽。 ```java import com.zaxxer.hikari.HikariConfig; import com.zaxxer.hikari.HikariDataSource; import java.sql.Connection; import java.sql.SQLException; public class ConnectionPoolExhaustedExample { public static void main(String[] args) { HikariConfig config = new HikariConfig(); config.setJdbcUrl("jdbc:mysql://localhost:3306/test"); config.setUsername("user"); config.setPassword("password"); config.setMaximumPoolSize(2); // 最大连接数为2 try (HikariDataSource dataSource = new HikariDataSource(config)) { // 模拟3个请求(连接池无法同时分配) for (int i = 0; i < 3; i++) { try { Connection conn = dataSource.getConnection(); System.out.println("Got connection " + i); // 注意:实际应用中需及时关闭连接! } catch (SQLException e) { System.err.println("Failed to get connection: " + e.getMessage()); } } } } } ``` **输出**: 前2个请求会成功获取连接,第3个请求会因连接池耗尽抛出`SQLException`。 --- ### 解决方案 1. **调整池大小**:根据实际负载增加线程池/连接池的最大容量。 2. **优化任务处理**:减少单个任务的执行时间,或使用异步非阻塞方式。 3. **合理配置队列**:线程池中使用有界队列(如`ArrayBlockingQueue`)并设置拒绝策略(如`AbortPolicy`、`CallerRunsPolicy`)。 4. **监控与告警**:实时监控资源池的使用率,提前预警。 5. **资源释放**:确保线程、数据库连接等资源在使用后及时释放(如`try-with-resources`)。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值