【问题标题】:java.util.concurrent.RejectedExecutionException while shutting down SpeechClient关闭 SpeechClient 时出现 java.util.concurrent.RejectedExecutionException
【发布时间】:2019-06-25 12:33:27
【问题描述】:

我正在使用 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)

【问题讨论】:

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


    【解决方案1】:

    RejectedExecutionException 被抛出是因为新任务在ThreadExecutor 关闭后显然已提交给它。这是由于ThreadExecutor - ThreadPoolExecutor.AbortPolicy 中设置的默认处理程序策略所致。

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

    由于您要手动关闭您的客户端 mSpeechClient.shutDown() 及其内部的 ThreadExecutor,为了解决问题,您可能需要将处理程序策略更改为以下之一:

    • ThreadPoolExecutor.CallerRunsPolicy,调用的线程 execute 本身运行任务。这提供了一个简单的反馈 控制机制将减慢新任务的速度 已提交。
    • ThreadPoolExecutor.DiscardPolicy,一个任务不能 被执行只是简单地删除。
    • ThreadPoolExecutor.DiscardOldestPolicy中,如果执行器没有关闭 down,工作队列头部的任务被丢弃,然后 重试执行(可能再次失败,导致 重复。)

    以上是对引用自ThreadPoolExecutorJavaDoc 的处理程序策略描述的解释。

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

    【讨论】:

    • 但是,当我在活动的 onDestroy 中调用它时它工作正常,它只会在我的活动打开时调用它时抛出异常。
    • @RoshaanFarrukh 我告诉过你,抛出异常是因为你尝试手动关闭执行器。我不知道您为什么要这样做,通常我们将关闭留给 Android 生命周期。
    • 我将它用作语音搜索功能,当用户完成搜索后,我需要将其关闭,否则如果我保持打开状态,我会收到此异常 com.google.api.gax.rpc .OutOfRangeException:io.grpc.StatusRuntimeException:OUT_OF_RANGE:音频超时错误:长时间没有音频。音频应该接近实时发送。
    • @RoshaanFarrukh 对于这种特殊情况,我无法为您提供帮助,因为我没有使用 SpeechClient 的经验。我告诉你的只是发生异常的原因以及解决它的可能方法。从那里你独自一人,除非..
    • 这个有什么好运气吗??
    猜你喜欢
    • 2018-02-02
    • 1970-01-01
    • 2017-12-17
    • 1970-01-01
    • 2012-01-29
    • 2021-04-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多