Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/304.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在调用调用堆栈外部的OperationFuture时SynchronizationContext中出现异常_Java_Google Cloud Sdk_Cloud Document Ai - Fatal编程技术网

Java 在调用调用堆栈外部的OperationFuture时SynchronizationContext中出现异常

Java 在调用调用堆栈外部的OperationFuture时SynchronizationContext中出现异常,java,google-cloud-sdk,cloud-document-ai,Java,Google Cloud Sdk,Cloud Document Ai,我正在使用谷歌的DocumentAI SDK,但这个错误似乎源于gRPC SDK。我在documenti中调用一个异步操作,它返回一个操作future。当我在创建未来的callstack框架内调用方法OperationFuture.get()时,代码会正确地阻塞,直到未来完成并正常继续。但是,如果创建future的方法返回,并且我在其创建框架之外调用OperationFuture.get(),我总是会得到以下堆栈跟踪异常 io.grpc.internal.ManagedChannelImpl$2

我正在使用谷歌的DocumentAI SDK,但这个错误似乎源于gRPC SDK。我在documenti中调用一个异步操作,它返回一个
操作future
。当我在创建未来的callstack框架内调用方法
OperationFuture.get()
时,代码会正确地阻塞,直到未来完成并正常继续。但是,如果创建future的方法返回,并且我在其创建框架之外调用
OperationFuture.get()
,我总是会得到以下堆栈跟踪异常

io.grpc.internal.ManagedChannelImpl$2 uncaughtException
SEVERE: [Channel<1>: (us-documentai.googleapis.com:443)] Uncaught exception in the SynchronizationContext. Panic!
java.util.concurrent.RejectedExecutionException: Task java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask@60d4b478 rejected from java.util.concurrent.ScheduledThreadPoolExecutor@1e3a60f5[Terminated, pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0]
    at java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:2063)
    at java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:830)
    at java.util.concurrent.ScheduledThreadPoolExecutor.delayedExecute(ScheduledThreadPoolExecutor.java:326)
    at java.util.concurrent.ScheduledThreadPoolExecutor.schedule(ScheduledThreadPoolExecutor.java:533)
    at java.util.concurrent.ScheduledThreadPoolExecutor.execute(ScheduledThreadPoolExecutor.java:622)
    at io.grpc.internal.ManagedChannelImpl$RealChannel$PendingCall.reprocess(ManagedChannelImpl.java:1089)
    at io.grpc.internal.ManagedChannelImpl$RealChannel.updateConfigSelector(ManagedChannelImpl.java:1022)
    at io.grpc.internal.ManagedChannelImpl$NameResolverListener$1NamesResolved.run(ManagedChannelImpl.java:1729)
    at io.grpc.SynchronizationContext.drain(SynchronizationContext.java:95)
    at io.grpc.SynchronizationContext.execute(SynchronizationContext.java:127)
    at io.grpc.internal.ManagedChannelImpl$NameResolverListener.onResult(ManagedChannelImpl.java:1815)
    at io.grpc.internal.DnsNameResolver$Resolve.run(DnsNameResolver.java:333)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)

我已经找到了问题的根源。操作在堆栈框架内工作而不在堆栈框架外工作的原因是创建和管理此
operationFuture
googleClient
对象有自己的
ExecutorService
处理
operationFuture
生命周期。一旦我们从
startAsync()
方法返回,
googleClient
对象就会超出范围并被释放,这也会释放与之关联的所有线程,并破坏
operationFuture
对象

为了解决这个问题,
googleClient
对象必须与
operationFuture
一起在内存中保持活动状态。例如,对于文档I:

public void startAsync() {
    ...
    this.googleClient = DocumentProcessorServiceClient.create(docAISettings);
    this.operationFuture = this.googleClient.doAsyncRequest();
    return;
}
只要future和客户端对象都没有超出范围,从外部调用
operationFuture.get()
方法现在就可以正常工作


我试图为
googleClient
对象提供一个自定义线程池,并让它进行垃圾收集(即
googleClient
对象死亡,但运行
operationFuture
的线程没有),但它似乎不起作用,不确定原因。

伪代码太通用,不够详细,无法调查错误,您可以分享更多或尝试复制的文章吗?我发现了问题,将尽快发布解决方案,这可能是因为operationFuture当前正在运行操作吗?您是否尝试取消任何排队的操作?也许你的GC需要一些微调?或者可以考虑使用不同的GC?你应该为GC问题打开一个线程。
public void startAsync() {
    ...
    this.googleClient = DocumentProcessorServiceClient.create(docAISettings);
    this.operationFuture = this.googleClient.doAsyncRequest();
    return;
}