- AbortPolicy(默认策略)
- 策略描述:当线程池饱和且无法处理新任务时,抛出
RejectedExecutionException
异常。
- 示例代码:
import java.util.concurrent.*;
public class AbortPolicyExample {
public static void main(String[] args) {
ThreadPoolExecutor executor = new ThreadPoolExecutor(
2, // 核心线程数
2, // 最大线程数
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<>(1), // 任务队列容量为1
new ThreadPoolExecutor.AbortPolicy());
for (int i = 0; i < 4; i++) {
int taskNumber = i;
executor.submit(() -> {
System.out.println("Task " + taskNumber + " is running on thread " + Thread.currentThread().getName());
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
});
}
executor.shutdown();
}
}
- 执行流程:线程池核心线程数和最大线程数都为2,任务队列容量为1。当提交第4个任务时,线程池和任务队列都已满,此时会抛出
RejectedExecutionException
异常,任务无法提交到线程池执行。
- CallerRunsPolicy
- 策略描述:当线程池饱和时,将被拒绝的任务交由调用者线程来执行。
- 示例代码:
import java.util.concurrent.*;
public class CallerRunsPolicyExample {
public static void main(String[] args) {
ThreadPoolExecutor executor = new ThreadPoolExecutor(
2, // 核心线程数
2, // 最大线程数
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<>(1), // 任务队列容量为1
new ThreadPoolExecutor.CallerRunsPolicy());
for (int i = 0; i < 4; i++) {
int taskNumber = i;
executor.submit(() -> {
System.out.println("Task " + taskNumber + " is running on thread " + Thread.currentThread().getName());
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
});
}
executor.shutdown();
}
}
- 执行流程:线程池核心线程数和最大线程数都为2,任务队列容量为1。当提交第4个任务时,线程池和任务队列都已满,该任务会在调用者线程(即
main
线程)中执行。所以会看到 main
线程也参与了任务的执行。
- DiscardOldestPolicy
- 策略描述:当线程池饱和时,丢弃任务队列中最老的任务(即队列头部的任务),然后尝试将新任务加入任务队列。
- 示例代码:
import java.util.concurrent.*;
public class DiscardOldestPolicyExample {
public static void main(String[] args) {
ThreadPoolExecutor executor = new ThreadPoolExecutor(
2, // 核心线程数
2, // 最大线程数
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<>(1), // 任务队列容量为1
new ThreadPoolExecutor.DiscardOldestPolicy());
for (int i = 0; i < 4; i++) {
int taskNumber = i;
executor.submit(() -> {
System.out.println("Task " + taskNumber + " is running on thread " + Thread.currentThread().getName());
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
});
}
executor.shutdown();
}
}
- 执行流程:线程池核心线程数和最大线程数都为2,任务队列容量为1。当提交第3个任务时,任务队列已满,此时会丢弃任务队列中最早的任务(第1个加入队列的任务),然后将第3个任务加入队列。当提交第4个任务时,又会重复上述过程,丢弃队列中最早的任务(第2个加入队列的任务),将第4个任务加入队列。所以最终只有第2、3、4个任务中的两个会被执行(因为线程池只有2个线程并行执行任务)。
- DiscardPolicy
- 策略描述:当线程池饱和时,直接丢弃被拒绝的任务,不做任何处理。
- 示例代码:
import java.util.concurrent.*;
public class DiscardPolicyExample {
public static void main(String[] args) {
ThreadPoolExecutor executor = new ThreadPoolExecutor(
2, // 核心线程数
2, // 最大线程数
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<>(1), // 任务队列容量为1
new ThreadPoolExecutor.DiscardPolicy());
for (int i = 0; i < 4; i++) {
int taskNumber = i;
executor.submit(() -> {
System.out.println("Task " + taskNumber + " is running on thread " + Thread.currentThread().getName());
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
});
}
executor.shutdown();
}
}
- 执行流程:线程池核心线程数和最大线程数都为2,任务队列容量为1。当提交第3个任务时,线程池和任务队列都已满,第3个任务直接被丢弃。当提交第4个任务时,同样被丢弃。所以最终只有第1、2个任务会被执行(因为线程池只有2个线程并行执行任务,且前两个任务能成功进入队列或被线程执行)。