线程池拒绝策略
在Java中,Executor线程池是通过ThreadPoolExecutor类实现的,你可以通过自定义拒绝策略来处理当线程池无法接受新任务时的情况。拒绝策略定义了当任务无法提交给线程池时应该采取的动作。
要自定义拒绝策略,你需要创建一个实现了RejectedExecutionHandler接口的类,并实现rejectedExecution()方法。该方法会在任务被拒绝时被调用,你可以在该方法中定义自己的逻辑来处理拒绝的任务。
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadPoolExecutor;
public class CustomRejectedExecutionHandler implements RejectedExecutionHandler {
@Override
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
// 自定义处理逻辑,例如记录日志或抛出异常
System.out.println("任务被拒绝: " + r.toString());
// 可以选择抛出异常或者其他处理方式
throw new RejectedExecutionException("任务被拒绝: " + r.toString());
}
}
然后,在创建线程池时,使用你自定义的拒绝策略:
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;
public class Main {
public static void main(String[] args) {
int threadPoolSize = 10;
int maxThreadPoolSize = 20;
long keepAliveTime = 60L;
ThreadPoolExecutor executor = new ThreadPoolExecutor(
threadPoolSize,
maxThreadPoolSize,
keepAliveTime,
TimeUnit.SECONDS,
new ArrayBlockingQueue<>(100),
new CustomRejectedExecutionHandler()
);
// 执行任务...
executor.execute(new MyTask());
}
}
在上述示例中,当任务被拒绝时,会打印一条消息并抛出RejectedExecutionException异常。你可以根据需要自定义拒绝策略的处理逻辑,例如记录日志、进行特定操作或选择不同的异常处理方式。
线程超时机制+cancel线程
在Java中,线程的超时时间是指在执行过程中限制线程的最大执行时间,如果线程在指定的时间内未能完成任务,则中断线程的执行。
一种常见的方式是在任务执行前使用Future和get()方法来设置线程的最大超时时间。get()方法可以指定一个超时时间,如果任务在该时间内未能完成,则会抛出TimeoutException异常。
import java.util.concurrent.*;
public class Main {
public static void main(String[] args) {
ExecutorService executor = Executors.newSingleThreadExecutor();
Callable<String> task = () -> {
// 模拟需要耗时的任务
Thread.sleep(5000);
return "任务执行完成";
};
Future<String> future = executor.submit(task);
try {
String result = future.get(3, TimeUnit.SECONDS); // 设置超时时间为3秒
System.out.println(result);
} catch (TimeoutException e) {
// 超时异常处理
System.out.println("任务执行超时");
future.cancel(true); // 中断线程的执行
} catch (InterruptedException | ExecutionException e) {
// 其他异常处理
e.printStackTrace();
}
executor.shutdown();
}
}
在上述示例中,创建了一个单线程的线程池,并提交了一个耗时的任务。使用future.get(3, TimeUnit.SECONDS)来设置超时时间为3秒。如果任务在3秒内未能完成,则会抛出TimeoutException异常。在异常处理中可以针对超时进行相应的操作,如中断线程的执行。
需要注意的是,在捕获到TimeoutException异常后,可以调用future.cancel(true)来中断线程的执行,参数true表示中断执行线程。这样可以提前终止任务的执行,但需要注意任务本身需要支持中断操作,否则中断操作可能无效。
另外,在使用ExecutorService时,记得在适当的时候调用shutdown()方法来关闭线程池,以确保资源正确释放。
ForkJoinPool
如果项目采用了类似于ForkJoinPool这种jdk提供的标准线程池库
ForkJoinPool内部使用ForkJoinWorkerThreadFactory来创建线程,并使用ForkJoinWorkerThread来表示工作线程。要自定义拒绝策略,你可以实现自己的ForkJoinWorkerThreadFactory,在工厂中创建自定义的ForkJoinWorkerThread,并设置拒绝策略。
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinWorkerThread;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
public class CustomForkJoinWorkerThreadFactory implements ForkJoinPool.ForkJoinWorkerThreadFactory {
private final RejectedExecutionHandler rejectedExecutionHandler;
public CustomForkJoinWorkerThreadFactory(RejectedExecutionHandler rejectedExecutionHandler) {
this.rejectedExecutionHandler = rejectedExecutionHandler;
}
@Override
public ForkJoinWorkerThread newThread(ForkJoinPool pool) {
return new CustomForkJoinWorkerThread(pool, rejectedExecutionHandler);
}
}
class CustomForkJoinWorkerThread extends ForkJoinWorkerThread {
private final RejectedExecutionHandler rejectedExecutionHandler;
protected CustomForkJoinWorkerThread(ForkJoinPool pool, RejectedExecutionHandler rejectedExecutionHandler) {
super(pool);
this.rejectedExecutionHandler = rejectedExecutionHandler;
}
@Override
protected void onStart() {
// 设置拒绝策略
ThreadPoolExecutor executor = (ThreadPoolExecutor) getPool();
executor.setRejectedExecutionHandler(rejectedExecutionHandler);
super.onStart();
}
}
class CustomRejectedExecutionHandler implements RejectedExecutionHandler {
@Override
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
// 自定义拒绝策略的处理逻辑
System.out.println("任务被拒绝: " + r.toString());
}
}
public class Main {
public static void main(String[] args) {
RejectedExecutionHandler rejectedExecutionHandler = new CustomRejectedExecutionHandler();
ThreadFactory threadFactory = new CustomForkJoinWorkerThreadFactory(rejectedExecutionHandler);
ForkJoinPool forkJoinPool = new ForkJoinPool(4, threadFactory, rejectedExecutionHandler, false);
// 执行任务...
forkJoinPool.invoke(new MyRecursiveTask());
}
}