因为我不是专门研究多线程的,所以问题可能很低级,甚至很愚蠢,请原谅=)
这里是我的代码调用流程;
messagenotificationjobexecutionconfig->asyncmessagenotificationjobexecutor->notificationjobexecutor.execute()
messagenotificationjobexecutionconfig(查找要处理的对象)并在循环内调用asyncmessagenotificationjobexecutor
asyncmessagenotificationjobexecutor在execute()方法上有@async(“messagenotificationtaskexecutor”)注解。
asyncmessagenotificationjobexecutor.execute()方法调用notificationjobexecutor.execute()
messagenotificationtaskexecutor是threadpooltaskexecutor的示例
这是我的问题;
如果我没有错作为默认notificationjobexecutor有一个单音示例。
即使asyncmessagenotificationjobexecutor异步工作并使用线程池任务执行器,所有线程也只调用notificationjobexecutor示例(单音)。
我不确定,我可能误解了线程\u 1调用notificationjobexecutor.execute(),在该线程完成其作业之前,其他线程将等待线程\u 1。我的推论正确吗?
我认为即使它看起来是多线程的,实际上它也是单音的
@Component("messageNotificationTaskExecutor")
public class MessageNotificationThreadPoolTaskExecutor extends ThreadPoolTaskExecutor {
@Value("${message.notification.task.executor.corePoolSize}")
Integer corePoolSize;
@Value("${message.notification.task.executor.maxPoolSize}")
Integer maxPoolSize;
@Value("${message.notification.task.executor.queueCapacity}")
Integer queueCapacity;
public MessageNotificationThreadPoolTaskExecutor() {
super();
}
@PostConstruct
public void init() {
super.setCorePoolSize(corePoolSize);
super.setMaxPoolSize(maxPoolSize);
super.setQueueCapacity(queueCapacity);
}
}
@Configuration
public class MessageNotificationJobExecutionConfig {
protected Logger log = LoggerFactory.getLogger(getClass());
@Autowired
AsyncMessageNotificationJobExecutor asyncMessageNotificationJobExecutor;
@Autowired
MessageNotificationThreadPoolTaskExecutor threadPoolTaskExecutor;
@Autowired
JobExecutionRouter jobExecutionRouter;
@Autowired
NotificationJobService notificationJobService;
private Integer operationType = OperationType.ACCOUNT_NOTIFICATION.getValue();
@Scheduled(cron = "${message.notification.scheduler.cronexpression}")
public void executePendingJobs() {
List<NotificationJob> nextNotificationJobList = notificationJobService.findNextJobForExecution(operationType, 10);
for (NotificationJob nextNotificationJob : nextNotificationJobList) {
if (threadPoolTaskExecutor.getActiveCount() < threadPoolTaskExecutor.getMaxPoolSize()) {
asyncMessageNotificationJobExecutor.execute(nextNotificationJob);
}
}
}
}
@Service
public class AsyncMessageNotificationJobExecutor {
@Autowired
NotificationJobExecutor notificationJobExecutor;
@Autowired
NotificationJobService notificationJobService;
@Async("messageNotificationTaskExecutor")
public void execute(NotificationJob notificationJob) {
notificationJobExecutor.execute(notificationJob);
}
}
@Component
public class NotificationJobExecutor implements JobExecutor {
@Override
public Integer getOperationType() {
return OperationType.ACCOUNT_NOTIFICATION.getValue();
}
@Override
public String getOperationTypeAsString() {
return OperationType.ACCOUNT_NOTIFICATION.name();
}
@Override
public void execute(NotificationJob notificationJob) {
// TODO: 20.08.2020 will be execute
}
}
1条答案
按热度按时间6fe3ivhb1#
在您创建的场景中,您拥有所有的单例示例。但流程看起来是这样的:
呼叫
executePendingJobs
在MessageNotificationJobExecutionConfig
迭代每个NotificationJob
顺序(所以这是等待)呼叫
execute
在AsyncMessageNotificationJobExecutor
它将向messageNotificationTaskExecutor
线程池的顺序(因此阻塞)在单独的线程中执行步骤3中创建的作业(因此这实际上是在
AsyncMessageNotificationJobExecutor
阻止呼叫execute
中的方法NotificationJobExecutor
“魔力”发生在第3步,在这里,spring将向messageNotificationTaskExecutor
这就结束了对第4步的调用。这导致对步骤4的调用是异步的,因此对同一示例的多个调用可以同时发生。所以确保这个对象是无状态的。