关闭SpeechClient时java.util.concurrent.RejectedExecutionException

时间:2019-06-25 12:33:27

标签: android speech-recognition google-speech-api

我正在使用Google Speech Client将语音转换为文本,它工作正常,但是当我尝试将其关闭时,会抛出异常。

这是我用于初始化的代码。

private val mSpeechClient by lazy {

    applicationContext.resources.openRawResource(R.raw.credentials).use {
        SpeechClient.create(SpeechSettings.newBuilder()
                .setCredentialsProvider { GoogleCredentials.fromStream(it) }
                .build())
    }
}

但是当我打电话

mSpeechClient.shutDown()

它抛出此异常。

 Process: com.google.cloud.examples.speechrecognition, PID: 10080
java.util.concurrent.RejectedExecutionException: Task java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask@11065d8d rejected from java.util.concurrent.ScheduledThreadPoolExecutor@3cbffe24[Terminated, pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 2]
    at java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:2011)
    at java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:793)
    at java.util.concurrent.ScheduledThreadPoolExecutor.delayedExecute(ScheduledThreadPoolExecutor.java:298)
    at java.util.concurrent.ScheduledThreadPoolExecutor.schedule(ScheduledThreadPoolExecutor.java:503)
    at java.util.concurrent.ScheduledThreadPoolExecutor.execute(ScheduledThreadPoolExecutor.java:592)
    at io.grpc.internal.SerializingExecutor.schedule(SerializingExecutor.java:93)
    at io.grpc.internal.SerializingExecutor.execute(SerializingExecutor.java:86)
    at io.grpc.internal.ClientCallImpl$ClientStreamListenerImpl.closed(ClientCallImpl.java:594)
    at io.grpc.internal.DelayedStream$DelayedStreamListener$4.run(DelayedStream.java:418)
    at io.grpc.internal.DelayedStream$DelayedStreamListener.delayOrExecute(DelayedStream.java:372)
    at io.grpc.internal.DelayedStream$DelayedStreamListener.closed(DelayedStream.java:415)
    at io.grpc.internal.AbstractClientStream$TransportState.closeListener(AbstractClientStream.java:392)
    at io.grpc.internal.AbstractClientStream$TransportState.access$300(AbstractClientStream.java:200)
    at io.grpc.internal.AbstractClientStream$TransportState$1.run(AbstractClientStream.java:376)
    at io.grpc.internal.AbstractClientStream$TransportState.deframerClosed(AbstractClientStream.java:245)
    at io.grpc.internal.Http2ClientStreamTransportState.deframerClosed(Http2ClientStreamTransportState.java:31)
    at io.grpc.okhttp.OkHttpClientStream$TransportState.deframerClosed(OkHttpClientStream.java:275)
    at io.grpc.internal.MessageDeframer.close(MessageDeframer.java:233)
    at io.grpc.internal.MessageDeframer.closeWhenComplete(MessageDeframer.java:195)
    at io.grpc.internal.AbstractStream$TransportState.closeDeframer(AbstractStream.java:180)
    at io.grpc.internal.AbstractClientStream$TransportState.transportReportStatus(AbstractClientStream.java:379)
    at io.grpc.okhttp.OkHttpClientTransport.startGoAway(OkHttpClientTransport.java:739)
    at io.grpc.okhttp.OkHttpClientTransport.access$1900(OkHttpClientTransport.java:92)
    at io.grpc.okhttp.OkHttpClientTransport$ClientFrameHandler.run(OkHttpClientTransport.java:936)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
    at java.lang.Thread.run(Thread.java:818)

1 个答案:

答案 0 :(得分:1)

抛出

RejectedExecutionException是因为显然新的任务在关闭后已提交给ThreadExecutor。发生这种情况是由于在ThreadExecutor-ThreadPoolExecutor.AbortPolicy中设置了默认处理程序策略。

  
      
  • 在默认的ThreadPoolExecutor.AbortPolicy中,处理程序抛出一个   拒绝时运行时RejectedExecutionException
  •   

由于您要手动关闭客户端mSpeechClient.shutDown(),并在其中使用ThreadExecutor,要解决该问题,您可能需要将处理程序策略更改为以下选项之一:< / p>

  
      
  • ThreadPoolExecutor.CallerRunsPolicy中,调用的线程   执行自己运行任务。这提供了简单的反馈   控制机制,将减慢新任务的执行速度   已提交。
  •   
  • ThreadPoolExecutor.DiscardPolicy中,无法执行的任务   被执行只是被丢弃。
  •   
  • ThreadPoolExecutor.DiscardOldestPolicy中,如果执行器未关闭   向下,放置在工作队列顶部的任务,然后   重试执行(这可能会再次失败,从而导致执行失败)   重复。)
  •   

上面是ThreadPoolExecutor JavaDoc中引用的处理程序策略描述的说明。

为此,您需要使用自己选择的策略设置创建ThreadExecutor的自定义实例,然后将其传递给客户端。这应该可以解决问题。