- AbortPolicy(中止策略)
- 特点:当任务添加到线程池被拒绝时,会抛出
RejectedExecutionException
异常。
- 场景:在一些对任务执行成功率要求极高,不允许任务丢失的场景中使用。例如,银行转账操作,每一个转账任务都必须确保执行,若任务被拒绝就抛出异常,方便开发者及时处理,避免转账丢失。代码示例:
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class AbortPolicyExample {
public static void main(String[] args) {
ThreadPoolExecutor executor = new ThreadPoolExecutor(
2,
2,
0L,
TimeUnit.MILLISECONDS,
new ArrayBlockingQueue<>(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(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
}
executor.shutdown();
}
}
- CallerRunsPolicy(调用者运行策略)
- 特点:当任务添加到线程池被拒绝时,该任务会被交给调用execute方法的线程来执行。这样做的好处是不会抛弃任务,也不会抛出异常,但是会影响调用者的性能。
- 场景:适用于处理一些对响应时间要求不是特别高,但又不希望任务被丢弃的场景。比如,在一个简单的日志记录系统中,若线程池满了,由调用记录日志的主线程来执行日志记录任务,虽然可能会稍微影响主线程性能,但能保证日志记录不会丢失。代码示例:
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class CallerRunsPolicyExample {
public static void main(String[] args) {
ThreadPoolExecutor executor = new ThreadPoolExecutor(
2,
2,
0L,
TimeUnit.MILLISECONDS,
new ArrayBlockingQueue<>(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(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
}
executor.shutdown();
}
}
- DiscardPolicy(丢弃策略)
- 特点:当任务添加到线程池被拒绝时,直接默默丢弃该任务,不做任何处理。
- 场景:在一些对任务执行结果不是特别关心,且任务量较大的场景下使用。例如,在一个高并发的访问统计系统中,偶尔丢失一些访问记录任务对整体统计结果影响不大,为了避免任务过多导致系统资源耗尽,可以采用此策略。代码示例:
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class DiscardPolicyExample {
public static void main(String[] args) {
ThreadPoolExecutor executor = new ThreadPoolExecutor(
2,
2,
0L,
TimeUnit.MILLISECONDS,
new ArrayBlockingQueue<>(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(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
}
executor.shutdown();
}
}
- DiscardOldestPolicy(丢弃最旧策略)
- 特点:当任务添加到线程池被拒绝时,会丢弃队列中最老的一个任务(即最先进入队列的任务),然后尝试把新任务加入队列。
- 场景:适用于任务执行时间较短,队列中任务可以被适当替换的场景。比如,在一个实时行情数据更新系统中,新的行情数据任务不断进来,如果线程池满了,丢弃最早的行情数据任务,让新的任务进入,以保证系统处理的是相对较新的数据。代码示例:
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class DiscardOldestPolicyExample {
public static void main(String[] args) {
ThreadPoolExecutor executor = new ThreadPoolExecutor(
2,
2,
0L,
TimeUnit.MILLISECONDS,
new ArrayBlockingQueue<>(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(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
}
executor.shutdown();
}
}