#java #multithreading #spring-boot
#java #многопоточность #spring-boot
Вопрос:
Я работаю над процессом, который выполняет следующую задачу :
1.Kafka Consumer consumes kafka message and does some task A
2.It then starts an async process using @Async in spring boot
3.It clears the context and exits
Я передаю контекст в Async с помощью TaskDecorator
public class AsyncTaskDecorator implements TaskDecorator {
ContextProvider provider = ContextProvider.getContext();
}
Ниже приведен мой класс ContextProvider
private static final ThreadLocal<CountryContextProvider> CONTEXT = new ThreadLocal<>();
public static void clear() {
CONTEXT.clear();
}
Проблема, с которой я сталкиваюсь, заключается в том, что родительский поток вызывает clear для контекста, прежде чем дочерний поток сможет скопировать его с помощью ContextProvider provider = ContextProvider.getContext();
Как мне убедиться, что дочерний поток может получить контекст до того, как родительский поток вызовет clear.Кроме того, я не могу заставить основной поток ждать дочернего потока, весь смысл использования Async заключается в том, чтобы позволить дочернему потоку выполняться независимо.
Ответ №1:
Что вы можете и должны сделать, так это удалить действие очистки контекста из родительского элемента и делегировать его самому дочернему элементу. Вы можете написать свой AsyncTaskDecorator, как показано ниже;
public class AsyncTaskDecorator implements TaskDecorator {
public Runnable decorate(Runnable runnable) {
return () -> {
try {
ContextProvider provider = ContextProvider.getContext();
// Use it here
} finally {
ContextProvider.getContext().clear();
}
};
}
}
Комментарии:
1. невозможно этого сделать, поскольку мы не можем предположить, что в неасинхронной части не будет исключений. Если перед вызовом async возникнет какое-либо исключение, контекст никогда не будет очищен