Java kombiniert Async und getrennte Threads, langsame Leistung
Posted: 02 Mar 2025, 14:18
Ich habe die folgende Funktion, die eine Liste zurückgibt, die die Namen der Audio-Dateien enthält, sobald sie heruntergeladen wurden: < /p>
Im Inneren verwende ich eine Talk Methode einer Dienstklasse in einem einfachen für Schleife:
Die Talk -Methode sendet eine Anforderung an die Azure -API und erstellt zwei Dinge:
[*] Erhält die SprachsynthesisResult Audio -Daten als Byte []
Die AZURE -Methode. Das Erhalten des Audio gibt nur zukünftige zurück, keine vollständige Future :
Daher muss ich die Blockierungsmethode aufrufen .get () , um das Audio zu erhalten. Um dieses Problem auszugleichen, drehe ich einen neuen parallelen Thread, um es zu tun: < /p>
Die WriteToFile -Methode ist eine Synchronisierungsmethode, die DateiOutputStream zum Schreiben des Byte [] Daten in eine Datei verwendet.
Code: Select all
List getAudios(List text)
Code: Select all
for (String s: text) {
futures.add(this.talkService.talk(s));
}
[*] Erhält die SprachsynthesisResult Audio -Daten als Byte []
Die AZURE -Methode. Das Erhalten des Audio gibt nur zukünftige zurück, keine vollständige Future :
Code: Select all
Future SpeakSsmlAsync(final String var1)
Code: Select all
CompletableFuture talk(String text) {
CompletableFuture completableFuture = new CompletableFuture();
SpeechSynthesizer speechSynthesizer = new SpeechSynthesizer(config, null);
...
taskExecutor.execute(() -> {
...
Future result = speechSynthesizer.SpeakSsmlAsync(ssmlText);
SpeechSynthesisResult audioResult = result.get();
if (audioResult.getReason() == ResultReason.SynthesizingAudioCompleted) {
byte[] data = audioResult.getAudioData();
String filename = this.fileService.writeToFile(data, "mp3");
completableFuture.complete(filename);
}
});
return completableFuture;
}
Code: Select all
public void action(List text) {
List audios = getAudios(text);
// wait for all audios to download and then get the list of names
List filenames = CompletableFuture.allOf(audios.toArray(new CompletableFuture[0]))
.thenApply((v) -> {
return audios.stream().map(CompletableFuture::join)
.collect(Collectors.toList());
}).join();
}
< /code>
Wenn ich jedoch die Protokollausgabe in der Konsole betrachte, scheint es, dass alle Audiodateien immer in korrekter Reihenfolge heruntergeladen werden, fast so wie nicht gleichzeitig. Code, und wie könnte es verbessert werden, was die leistungsfähige Leistung verbessert wird?@SpringBootApplication(exclude = {SecurityAutoConfiguration.class})
public class MyApplication {
@Bean
public ThreadPoolTaskExecutor taskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
return executor;
}
...