Заставить основной поток ждать, пока контекст не будет скопирован дочерними потоками

#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 возникнет какое-либо исключение, контекст никогда не будет очищен