java.util.concurrent.RejectedExecutionException при завершении работы SpeechClient - PullRequest
1 голос
/ 25 июня 2019

Я использую 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 Ответ

1 голос
/ 25 июня 2019

RejectedExecutionException выбрасывается, потому что новые задачи были отправлены на ThreadExecutor после его закрытия. Это происходит из-за политики обработчика по умолчанию, установленной в ThreadExecutor - ThreadPoolExecutor.AbortPolicy.

  • По умолчанию ThreadPoolExecutor.AbortPolicy обработчик выдает время выполнения RejectedExecutionException при отклонении.

Поскольку вы закрываете вручную ваш клиент mSpeechClient.shutDown() и внутри него ThreadExecutor, для решения проблемы вы можете изменить политику обработчика на одно из следующих:

  • In ThreadPoolExecutor.CallerRunsPolicy, поток, который вызывает Выполнить сам запускает задачу. Это обеспечивает простую обратную связь механизм управления, который замедлит скорость появления новых задач представленный.
  • В ThreadPoolExecutor.DiscardPolicy, задача, которая не может быть выполненным просто отброшено.
  • В ThreadPoolExecutor.DiscardOldestPolicy, если исполнитель не закрыт вниз, задача во главе рабочей очереди удаляется, а затем выполнение повторяется (что может снова завершиться сбоем, вызывая это повторяется.)

Выше приведено объяснение описаний политик обработчиков, приведенных в ThreadPoolExecutor JavaDoc.

Для этого вам нужно создать пользовательский экземпляр ThreadExecutor с выбранным параметром политики, а затем передать его своему клиенту. Это должно решить проблему.

...