当线程池中的任务缓存队列已满,且线程数目达到maximumPoolSize时,如果还有任务到来就会采取任务拒绝策略,通常有以下四种策略:
AbortPolicy:丢弃任务并抛出RejectedExecutionException异常。
DiscardPolicy:也是丢弃任务,但是不抛出异常。
DiscardOldestPolicy:丢弃队列最前面的任务,然后重新尝试执行任务(重复此过程)
CallerRunsPolicy:由调用线程处理该任务
这种策略不会造成数据丢失,且可以减缓任务的提交速度,一般在异步任务批处理时使用
我们可以通过重写RejectedExecutionHandler来自定义一种拒绝或降级策略:
package com.example.demo;
import com.alibaba.fastjson.JSON;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import javax.annotation.PostConstruct;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
@Slf4j
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
public class ThreadPoolTest {
@Test
public void threadPoolRejectedPolicyTest() {
Student student1 = new Student("zhangsan", 23);
Student student2 = new Student("lisi", 24);
AsyncSaveStudentTask task1 = new AsyncSaveStudentTask(student1);
AsyncSaveStudentTask task2 = new AsyncSaveStudentTask(student2);
asyncTaskExecutor.execute(task1);
asyncTaskExecutor.execute(task2);
}
private ThreadPoolTaskExecutor asyncTaskExecutor;
@PostConstruct
private void init() {
asyncTaskExecutor = new ThreadPoolTaskExecutor();
ThreadFactory factory = new ThreadFactoryBuilder().setDaemon(true).setNameFormat("threadName" + "%d").build();
asyncTaskExecutor.setThreadFactory(factory);
asyncTaskExecutor.setCorePoolSize(1);
asyncTaskExecutor.setMaxPoolSize(1);
asyncTaskExecutor.setAllowCoreThreadTimeOut(true);
asyncTaskExecutor.setQueueCapacity(0);
asyncTaskExecutor.setKeepAliveSeconds(3);
asyncTaskExecutor.setDaemon(true);
asyncTaskExecutor.setRejectedExecutionHandler(new RejectedExecutionHandler() {
@Override
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
log.error("转MQ处理");
executorFailSendMQ(r);
}
});
asyncTaskExecutor.initialize();
}
private void executorFailSendMQ(Runnable r){
try {
AsyncSaveStudentTask task = (AsyncSaveStudentTask) r;
//从线程池失败中获取student对象
Student student = task.getStudent();
log.info("executorFailSendMQ send ={}",JSON.toJSONString(student));
//重新发送mq
}catch (Exception e){
log.error("executorFailSendMQ error",e);
}
}
class AsyncSaveStudentTask implements Runnable {
private Student student;
public AsyncSaveStudentTask(Student student) {
this.student = student;
}
public Student getStudent() {
return student;
}
@Override
public void run() {
System.out.println("AsyncSaveTask thread ={}" + Thread.currentThread().getName());
}
}
@Data
@AllArgsConstructor
public static class Student {
private String name;
private int age;
}
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。