java—springboot中的单线程和多线程真的是多线程吗?

w8f9ii69  于 2021-07-09  发布在  Java
关注(0)|答案(1)|浏览(685)

因为我不是专门研究多线程的,所以问题可能很低级,甚至很愚蠢,请原谅=)
这里是我的代码调用流程;
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 
    }

}
6fe3ivhb

6fe3ivhb1#

在您创建的场景中,您拥有所有的单例示例。但流程看起来是这样的:
呼叫 executePendingJobsMessageNotificationJobExecutionConfig 迭代每个 NotificationJob 顺序(所以这是等待)
呼叫 executeAsyncMessageNotificationJobExecutor 它将向 messageNotificationTaskExecutor 线程池的顺序(因此阻塞)
在单独的线程中执行步骤3中创建的作业(因此这实际上是在 AsyncMessageNotificationJobExecutor 阻止呼叫 execute 中的方法 NotificationJobExecutor “魔力”发生在第3步,在这里,spring将向 messageNotificationTaskExecutor 这就结束了对第4步的调用。这导致对步骤4的调用是异步的,因此对同一示例的多个调用可以同时发生。所以确保这个对象是无状态的。

相关问题