@@ -34,7 +34,7 @@ public final class SpeechSynthesizerV2 implements AudioWebsocketCallback {
3434 private SpeechSynthesisState state = SpeechSynthesisState .IDLE ;
3535 private ResultCallback <SpeechSynthesisResult > callback ;
3636
37- private AtomicReference <CountDownLatch > stopLatch = new AtomicReference <>(null );
37+ private final AtomicReference <CountDownLatch > stopLatch = new AtomicReference <>(null );
3838
3939 private SpeechSynthesisParam parameters ;
4040
@@ -48,7 +48,7 @@ public final class SpeechSynthesizerV2 implements AudioWebsocketCallback {
4848 private double recvAudioLength = 0 ;
4949 @ Getter @ Setter private long startedTimeout = 5000 ;
5050 @ Getter @ Setter private long firstAudioTimeout = -1 ;
51- private AtomicReference <CountDownLatch > startLatch = new AtomicReference <>(null );
51+ private final AtomicReference <CountDownLatch > startLatch = new AtomicReference <>(null );
5252 private AudioWebsocketRequest websocketRequest ;
5353 private String websocketUrl = Constants .baseWebsocketApiUrl ;
5454 private JsonObject bailianHeader = new JsonObject ();
@@ -102,8 +102,8 @@ public void updateParamAndCallback(
102102 this .canceled .set (false );
103103
104104 // reset inner params
105- this .stopLatch = new AtomicReference <> (null );
106- this .startLatch = new AtomicReference <> (null );
105+ this .stopLatch . set (null );
106+ this .startLatch . set (null );
107107 this .firstAudioTimeout = -1 ;
108108 this .isFirst = true ;
109109 this .audioStream = new ByteArrayOutputStream ();
@@ -168,6 +168,20 @@ public void close() {
168168 log .warn ("Failed to close websocket connection: " + e .getMessage ());
169169 }
170170 }
171+ releaseLatches ();
172+ }
173+
174+ /** Release startLatch and stopLatch to unblock any waiting threads. */
175+ private void releaseLatches () {
176+ CountDownLatch startLatch = this .startLatch .get ();
177+ if (startLatch != null && startLatch .getCount () > 0 ) {
178+ startLatch .countDown ();
179+ }
180+
181+ CountDownLatch stopLatch = this .stopLatch .get ();
182+ if (stopLatch != null && stopLatch .getCount () > 0 ) {
183+ stopLatch .countDown ();
184+ }
171185 }
172186
173187 private synchronized void sendTaskMessage (String action , JsonObject input ) {
@@ -308,16 +322,7 @@ public void onError(WebSocket webSocket, Throwable t) {
308322 // callback error first
309323 callback .onError (new ApiException (t ));
310324 }
311-
312- CountDownLatch startLatch = this .startLatch .get ();
313- if (startLatch != null && startLatch .getCount () > 0 ) {
314- startLatch .countDown ();
315- }
316-
317- CountDownLatch stopLatch = this .stopLatch .get ();
318- if (stopLatch != null && stopLatch .getCount () > 0 ) {
319- stopLatch .countDown ();
320- }
325+ releaseLatches ();
321326
322327 if (audioStream != null ) {
323328 audioStream .reset ();
@@ -327,21 +332,24 @@ public void onError(WebSocket webSocket, Throwable t) {
327332 @ Override
328333 public void onClose (int code , String reason ) {
329334 log .warn ("WebSocket connection closed: " + reason + " (" + code + ")" );
335+ releaseLatches ();
330336 }
331337
332338 private void handleTaskStarted (JsonObject message ) {
333339 log .info ("Task started" );
334340 state = SpeechSynthesisState .TTS_STARTED ;
335341 firstPackageTimeStamp = -1 ;
336- if (startLatch .get () != null ) {
337- startLatch .get ().countDown ();
342+ CountDownLatch startLatch = this .startLatch .get ();
343+ if (startLatch != null ) {
344+ startLatch .countDown ();
338345 }
339346 }
340347
341348 private void handleTaskFinished (JsonObject message ) {
342349 log .info ("Task finished" );
343- if (stopLatch .get () != null ) {
344- stopLatch .get ().countDown ();
350+ CountDownLatch stopLatch = this .stopLatch .get ();
351+ if (stopLatch != null ) {
352+ stopLatch .countDown ();
345353 }
346354 if (callback != null ) {
347355 callback .onComplete ();
@@ -370,8 +378,9 @@ private void handleTaskFailed(JsonObject message) {
370378 .build ();
371379 callback .onError (new ApiException (status ));
372380 }
373- if (stopLatch .get () != null ) {
374- stopLatch .get ().countDown ();
381+ CountDownLatch stopLatch = this .stopLatch .get ();
382+ if (stopLatch != null ) {
383+ stopLatch .countDown ();
375384 }
376385 }
377386
@@ -421,9 +430,10 @@ private void startStream(boolean enableSsml) throws NoApiKeyException, Interrupt
421430 }
422431
423432 checkConnectStatus (); // check websocket connection, if socket is closed.
424- startLatch = new AtomicReference <>(new CountDownLatch (1 ));
433+ CountDownLatch startLatch = new CountDownLatch (1 );
434+ this .startLatch .set (startLatch );
425435 startSynthesizer (enableSsml );
426- boolean startResult = startLatch .get (). await (startedTimeout , TimeUnit .MILLISECONDS );
436+ boolean startResult = startLatch .await (startedTimeout , TimeUnit .MILLISECONDS );
427437 if (!startResult ) {
428438 throw new RuntimeException (
429439 "TimeoutError: waiting for task started more than " + startedTimeout + " ms." );
@@ -458,25 +468,24 @@ public void streamingComplete(long completeTimeoutMillis) {
458468 "State invalid: expect stream input tts state is started but " + state .getValue ()));
459469 }
460470 }
461- stopLatch = new AtomicReference <>(new CountDownLatch (1 ));
471+ CountDownLatch stopLatch = new CountDownLatch (1 );
472+ this .stopLatch .set (stopLatch );
462473 stopSynthesizer ();
463474
464- if (stopLatch .get () != null ) {
465- try {
466- if (completeTimeoutMillis > 0 ) {
467- log .debug ("start waiting for stopLatch" );
468- if (!stopLatch .get ().await (completeTimeoutMillis , TimeUnit .MILLISECONDS )) {
469- throw new RuntimeException ("TimeoutError: waiting for streaming complete" );
470- }
471- } else {
472- log .debug ("start waiting for stopLatch" );
473- stopLatch .get ().await ();
475+ try {
476+ if (completeTimeoutMillis > 0 ) {
477+ log .debug ("start waiting for stopLatch" );
478+ if (!stopLatch .await (completeTimeoutMillis , TimeUnit .MILLISECONDS )) {
479+ throw new RuntimeException ("TimeoutError: waiting for streaming complete" );
474480 }
475- log .debug ("stopLatch is done" );
476- } catch (InterruptedException ignored ) {
477- log .error ("Interrupted while waiting for streaming complete" );
478- Thread .currentThread ().interrupt ();
481+ } else {
482+ log .debug ("start waiting for stopLatch" );
483+ stopLatch .await ();
479484 }
485+ log .debug ("stopLatch is done" );
486+ } catch (InterruptedException ignored ) {
487+ log .error ("Interrupted while waiting for streaming complete" );
488+ Thread .currentThread ().interrupt ();
480489 }
481490 }
482491
0 commit comments