1:创建核心线程数为5的固定线程池
java
package com.example.exerciseThreadPool;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class FixedThreadPoolDemo {
public static void main(String[] args) {
//1.创建核心线程数为5的固定线程池
ExecutorService executor = Executors.newFixedThreadPool(5);
//2.提交10个任务
for (int i = 1; i <= 10; i++) {
final int taskId = i;
executor.submit(() -> {
System.out.println("任务" + taskId + "开始执行,线程:" + Thread.currentThread().getName());
try {
//模拟耗时操作
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
System.out.println("任务" + taskId + "执行完毕");
});
}
//3.关闭线程池
executor.shutdown();
try {
if (!executor.awaitTermination(60, TimeUnit.SECONDS)) {
executor.shutdownNow();
}
} catch (InterruptedException e) {
executor.shutdownNow();
}
}
}
2:自定义线程池行为验证,深入理解corePoolSize,maximumPoolSize,workQueue和拒绝策略的关系
java
package com.example.exerciseThreadPool;
import java.util.concurrent.*;
public class ThreadPoolParamsDemo {
//自定义线程池行为验证,深入理解corePoolSize,maximumPoolSize,workQueue和拒绝策略的关系
public static void main(String[] args) {
//配置参数
int corePoolSize = 2;
int maximumPoolSize = 4;
long keepAliveTime = 60;
TimeUnit unit = TimeUnit.SECONDS;
//容量为2的有界队列
BlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<>(2);
ThreadFactory threadFactory = Executors.defaultThreadFactory();
//默认拒绝策略:抛出异常
RejectedExecutionHandler handler = new ThreadPoolExecutor.AbortPolicy();
ThreadPoolExecutor executor = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory, handler);
System.out.println("---开始提交任务---");
for (int i = 1; i <= 8; i++) {
final int taskId = i;
try {
executor.execute(() -> {
System.out.println("任务" + taskId + "正在运行,线程" + Thread.currentThread().getName());
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
});
System.out.println("任务" + taskId + "已提交");
} catch (RejectedExecutionException e) {
System.out.println("任务" + taskId + "被拒绝" + e.getMessage());
}
}
executor.shutdown();
}
}
3:监控线程池状态,获取运行时数据
java
package com.example.exerciseThreadPool;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class ThreadPoolMonitorDemo {
public static void main(String[] args) throws InterruptedException {
ThreadPoolExecutor executor = new ThreadPoolExecutor(2, 4, 60, TimeUnit.SECONDS, new ArrayBlockingQueue<>(2));
//提交一些事务
for (int i = 0; i < 6; i++) {
executor.submit(() -> {
try {
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
}
});
}
//短暂等待后打印状态
TimeUnit.MILLISECONDS.sleep(500);
System.out.println("活跃线程数" + executor.getActiveCount());
System.out.println("当前线程池大小" + executor.getPoolSize());
System.out.println("队列等待任务数" + executor.getQueue().size());
System.out.println("已完成任务数" + executor.getCompletedTaskCount());
executor.shutdownNow();
}
}
4:多线程抢红包(线程安全),结合线程池与锁机制解决资源竞争
java
package com.example.exerciseThreadPool;
import java.math.BigDecimal;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.locks.ReentrantLock;
public class RedPacketDemo {
//多线程抢红包(线程安全),结合线程池与锁机制解决资源竞争
private static BigDecimal totalAmount = new BigDecimal("10.00");
private static final ReentrantLock lock = new ReentrantLock();
private static int remainingPeople = 10;
public static void main(String[] args) {
ExecutorService executor = Executors.newFixedThreadPool(10);
for (int i = 1; i <= 10; i++) {
final int personId = i;
executor.submit(() -> {
lock.lock();
try {
if (remainingPeople > 0) {
BigDecimal amount;
if (remainingPeople == 1) {
// 最后一个人拿走剩余所有
amount = totalAmount;
} else {
//随机金额逻辑简化:每人至少0.01,最多剩余金额的均值*2
BigDecimal max = totalAmount.divide(new BigDecimal(remainingPeople), 2, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal("2"));
//简单模拟:取剩余金额的10%-20%作为随机范围,此处简化为固定比例演示
double randomRatio = Math.random() * 0.1 + 0.05;
amount = totalAmount.multiply(new BigDecimal(randomRatio)).setScale(2, BigDecimal.ROUND_HALF_DOWN);
//确保不超过剩余金额且不低于0.01
if (amount.compareTo(totalAmount) > 0) {
amount = totalAmount;
}
if (amount.compareTo(new BigDecimal("0.01")) < 0) {
amount = new BigDecimal("0.01");
}
}
totalAmount = totalAmount.subtract(amount);
remainingPeople--;
System.out.println("用户" + personId + "抢到" + amount + ",剩余" + totalAmount);
}
} finally {
lock.unlock();
}
});
}
executor.shutdown();
}
}
注意事项:
1:关闭线程池:务必在程序结束前调用shutdown()或shutdownNow(),否则JVM可能无法退出。
2:避免OOM:生产环境使用ThreadPoolExecutor构造函数并指定有界队列。
3:异常处理:在线程池任务中抛出的未捕获异常不会传播到主线程,建议在任务内部进行try-catch处理,或通过Thread.UncaughtExceptionHandler进行全局捕获。