Java线程池封装及拒绝策略示例详解
引言
在Java多线程编程中,合理地使用线程池可以提高程序的性能和效率。本文将详细讲解Java线程池的封装及拒绝策略,并提供示例代码说明。
线程池的封装
线程池的封装主要包括以下几个步骤:
- 创建线程池对象。可以通过
Executors
类提供的静态方法来创建不同类型的线程池,如newFixedThreadPool
、newCachedThreadPool
等。 - 定义任务。将需要执行的任务封装成
Runnable
或Callable
对象。 - 提交任务到线程池。通过线程池的
execute
或submit
方法提交任务,线程池会自动分配线程来执行任务。 - 关闭线程池。当不再需要线程池时,通过调用线程池的
shutdown
或shutdownNow
方法来关闭线程池。
下面是一个示例代码,演示了线程池的封装:
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ThreadPoolExample {
public static void main(String[] args) {
ExecutorService executor = Executors.newFixedThreadPool(5);
for (int i = 0; i < 10; i++) {
Runnable task = new MyTask(i);
executor.execute(task);
}
executor.shutdown();
}
}
class MyTask implements Runnable {
private int taskId;
public MyTask(int taskId) {
this.taskId = taskId;
}
@Override
public void run() {
System.out.println("Task " + taskId + " is running.");
// 执行任务的具体逻辑
}
}
在上面的示例中,我们创建了一个固定大小为5的线程池,并提交了10个任务给线程池执行。
拒绝策略示例
当线程池中的线程已满,并且任务队列已满时,线程池默认的处理方式是抛出RejectedExecutionException
异常。为了避免这种情况,我们可以自定义拒绝策略。
Java提供了四种默认的拒绝策略:
1. AbortPolicy
:默认的拒绝策略,抛出RejectedExecutionException
异常。
2. CallerRunsPolicy
:将任务添加到调用线程中执行。
3. DiscardOldestPolicy
:丢弃最早的未处理任务,并尝试重新提交当前任务。
4. DiscardPolicy
:直接丢弃未处理的任务。
可以通过调用ThreadPoolExecutor
的构造函数来自定义拒绝策略。下面是一个示例代码,演示了自定义拒绝策略:
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class CustomRejectedExecutionHandlerExample {
public static void main(String[] args) {
// 自定义拒绝策略
ThreadPoolExecutor executor = new ThreadPoolExecutor(
2, // 核心线程数
5, // 最大线程数
1, // 空闲线程存活时间
TimeUnit.MINUTES, // 时间单位
new ArrayBlockingQueue<>(5), // 任务队列
new CustomRejectedExecutionHandler() // 自定义的拒绝策略
);
for (int i = 0; i < 10; i++) {
Runnable task = new MyTask(i);
executor.execute(task);
}
executor.shutdown();
}
}
class CustomRejectedExecutionHandler implements RejectedExecutionHandler {
@Override
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
System.out.println("任务被拒绝:" + r.toString() + ",执行任务的线程池:" + executor.toString());
// 可以根据需求自定义拒绝策略,如将任务添加到其他队列或记录日志等
}
}
class MyTask implements Runnable {
private int taskId;
public MyTask(int taskId) {
this.taskId = taskId;
}
@Override
public void run() {
System.out.println("Task " + taskId + " is running.");
// 执行任务的具体逻辑
}
}
在上面的示例中,我们创建了一个线程池,使用了自定义的拒绝策略CustomRejectedExecutionHandler
。当线程池的线程已满,并且队列已满时,会调用自定义的拒绝策略的rejectedExecution
方法。
总结
本文详细讲解了Java线程池的封装及拒绝策略,并提供了示例代码说明。合理使用线程池可以提高多线程程序的性能和效率,同时通过自定义拒绝策略可以灵活处理线程池无法处理的任务。希望本文能够对你有所帮助。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:java 线程池封装及拒绝策略示例详解 - Python技术站