Если проблема заключается в дополнительном времени компиляции и раздувании бинарного размера, полученном путем компиляции .h как части всех используемых им .cpp-модулей, во многих случаях то, что вы можете сделать, - это сделать класс шаблона опустившимся из не-шаблонного базовый класс для не зависящих от типа частей интерфейса, и что базовый класс может иметь свою реализацию в файле .cpp.
В моем случае @Async
метод был определен в том же классе как синхронизирующий метод, который использовал его, и это, по-видимому, заставило все задания зависать на текущем потоке.
Плохой
@Component
@EnableAsync
public class TranslationGapiReader {
@Async
public CompletableFuture<GapiFile> readFile(String fileId) {
try { Thread.sleep(2000); } catch (Exception exc) { throw new RuntimeException("ololo", exc); }
return CompletableFuture.completedFuture(null);
}
public Stream<GapiFile> readFiles(Iterable<String> fileIds) {
List<CompletableFuture<GapiFile>> futures = new ArrayList<>();
for (String fileId: fileIds) {
futures.add(readFile(fileId));
}
return Stream.empty();
}
}
Хороший
@Component
@EnableAsync
public class AsyncGapiFileReader {
@Async
public CompletableFuture<TranslationGapiReader.GapiFile> readFile(String fileId) {
try { Thread.sleep(2000); } catch (Exception exc) { throw new RuntimeException("ololo", exc); }
return CompletableFuture.completedFuture(null);
}
}
@Component
@EnableAsync
public class TranslationGapiReader {
@Autowired
AsyncGapiFileReader asyncGapiFileReader;
public Stream<GapiFile> readFiles(Iterable<String> fileIds) {
List<CompletableFuture<GapiFile>> futures = new ArrayList<>();
for (String fileId: fileIds) {
futures.add(asyncGapiFileReader.readFile(fileId));
}
return Stream.empty();
}
}
я не гуру Spring достаточно для понимания, почему делает это, только работают, когда @Async
метод находится в другом классе, но это - то, что устраняет проблему от моих наблюдений.