SpringBoot中的java单线程和多线程。真的是多线程吗?
因为我不是专门研究多线程,所以问题可能是低级的,甚至是愚蠢的,请原谅=)
下面是我的代码调用流程图
MessageNotificationJobExecutionConfig->;AsyncMessageNotificationJobExecutor->;通知作业执行器。执行()
MessageNotificationJobExecutionConfig(查找要处理的对象)并在循环内调用AsyncMessageNotificationJobExecutor
AsyncMessageNotificationJobExecutor在execute()方法上有@Async(“messageNotificationTaskExecutor”)注释
AsyncMessageNotificationJobExecutor。execute()方法调用NotificationJobExecutor。执行()
messageNotificationTaskExecutor是ThreadPoolTaskExecutor
这是我的问题
如果我没有错,默认情况下,通知JobExecutor有一个单音实例
即使AsyncMessageNotificationJobExecutor异步工作并使用线程池任务执行器,所有线程都只调用NotificationJobExecutor实例(单音)
我不确定,我可能会误解线程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 楼答案
在您创建的场景中,您拥有所有单例实例。但是流看起来是这样的:
MessageNotificationJobExecutionConfig
中调用executePendingJobs
NotificationJob
(因此这是等待)AsyncMessageNotificationJobExecutor
中的execute
,这将向线程池中的messageNotificationTaskExecutor
顺序(从而阻塞)添加执行AsyncMessageNotificationJobExecutor
中的方法)NotificationJobExecutor
中的execute
方法的阻塞调用“神奇”发生在步骤3中,Spring将向
messageNotificationTaskExecutor
添加一个作业,而不是执行方法,该作业将封装对步骤4的调用。这导致对步骤4的调用是异步的,因此对同一实例的多个调用可以同时发生。因此,请确保此对象是无状态的