我使用Java编程与微控制器进行RPC风格的通信。我面临的问题是阻止客户端代码执行,直到我收到微控制器的结果,这是非同步的。
即,我发出命令并在两个不同的线程(相同的类)中接收结果。我采用的方法是使用CompletableFuture,但这并不像我预期的那样有效。
我的RPC调用方法发出命令并实例化CompletableFuture,如下所示:
pygame.display.set_mode((w, h))
在看起来像这样的调用代码中:
protected synchronized CompletableFuture<String> sendCommand(String command) {
... send command ...
this.handler = new CompletableFuture<String>();
return this.handler;
}
接下来,有一个从微控制器接收数据的监听方法:
CompletableFuture<String> result = procedure.sendCommand("readSensor(0x1508)");
String result = result.get(5, TimeUnit.SECONDS); // line X
我希望客户端代码执行将在X行阻塞,它确实会这样做。但由于某种原因,行Y不会解除阻塞,导致超时异常。
回答以下评论......
致电代码(对不起,名字与我上面提供的内容完全不符,但我认为这是唯一的区别):
protected synchronized void onReceiveResult(String data) {
this.handler.complete(data); // line Y
}
产生输出:
CompletableFuture<String> result = this.device.sendCommand(cmd);
log.debug("Waiting for callback, result=" + result);
String sid = result.get(timeout, unit);
完成代码:
2016-10-14 21:58:30 DEBUG RemoteProcedure:36 - Waiting for callback, result=com.***.rpc.RemoteDevice$ActiveProcedure@44c519a2[Not completed]
产生输出:
log.debug("Dispatching msg [" + msg + "] to a procedure: " + this.commandForResult);
log.debug("result=" + this.result);
log.debug("Cancelled = " + this.result.isCancelled());
log.debug("Done = " + this.result.isDone());
log.debug("CompletedExceptionally = " + this.result.isCompletedExceptionally());
boolean b = this.result.complete(msg);
this.result = null;
log.debug("b=" + b);
ActiveProcedure是实际的CompletableFuture:
2016-10-14 21:58:35 DEBUG RemoteDevice:141 - Dispatching msg [123] to a procedure: getId;
2016-10-14 21:58:35 DEBUG RemoteDevice:142 - result=com.***.rpc.RemoteDevice$ActiveProcedure@44c519a2[Not completed]
2016-10-14 21:58:35 DEBUG RemoteDevice:143 - Cancelled = false
2016-10-14 21:58:35 DEBUG RemoteDevice:144 - Done = false
2016-10-14 21:58:35 DEBUG RemoteDevice:145 - CompletedExceptionally = false
2016-10-14 21:58:35 DEBUG RemoteDevice:150 - b=true
答案 0 :(得分:0)
确定。事情很清楚:
底层库存在集成问题,我用它来与微控制器通信。我希望我在一个单独的线程中从设备接收数据,但这发生在同一个线程中。因此CompletableFuture.get没有取消阻止。
我不完全理解导致此类行为的机制,但放置
handler.complete(msg);
进入一个单独的线程解决了这个问题。