处理回调消息的Java实现
我需要在代码中处理以下情况:处理回调消息的Java实现,java,algorithm,design-patterns,Java,Algorithm,Design Patterns,我需要在代码中处理以下情况: public class Class1 { IRequester requester; public Class1(Requester impl) { requester = impl; } public List doSomething() { requester.request1(); // sends messages to a set of nodes //do some
public class Class1 {
IRequester requester;
public Class1(Requester impl) {
requester = impl;
}
public List doSomething() {
requester.request1(); // sends messages to a set of nodes
//do some more local processing
list = requester.request2(); // sends some more messages and returns a list
return list;
}
}
在本例中,request1()向一组节点发送一个请求并返回一个结果,该结果将在本地用于更多处理,然后生成request2(),该结果返回一个列表。这需要在doSomething()的执行结束时返回。request1()和request2()是通过IRequester类型的requester完成的
public interface IRequester {
request1();
List request2();
}
现在request1()和request2()由实际执行请求的类实现。这是处理节点之间通信的类
public NetworkManager implements IRequester {
request1() {
// Create an operation
// Add callback to the operation
// schedule operation
}
request2() {
}
}
现在,我的问题是,当我在这里实现request1()时,我需要创建一个过程,该过程将向节点发送消息。此过程可以附加回调。当节点响应时,它返回结果。如何实现这一点,使其在请求结束时返回结果1?其中一种方法是使用
CompletableFuture
跟踪异步值
public NetworkManager implements IRequester {
Client client; //some client that works with callbacks
CompletableFuture<String> request1() {
CompletableFuture<String> result = new CompletableFuture<>();
client.request1(someArguments, (calbackResult) -> result.complete(calbackResult));
return result;
}
}
公共网络管理器实现IRequester{
Client-Client;//使用回调的某个客户端
CompletableFuture request1(){
CompletableFuture结果=新建CompletableFuture();
request1(someArguments,(calbackResult)->result.complete(calbackResult));
返回结果;
}
}
这里的result
承诺在执行回调时,它将提供一个值。在此之前,它将是空的
所以NetworkManager
返回CompletableFuture
,这意味着结果尚未准备好或永远不会准备好(如果回调从未发生)
当Class1.doSomething
尝试从CompletableFuture
获取结果时,当前线程将阻塞,直到值可用或出现超时
这种方法还使
Class1.doSomething
中的代码更加稳定,因为它现在被迫处理超时和缺少结果的问题。其中一种方法是使用CompletableFuture
跟踪异步值
public NetworkManager implements IRequester {
Client client; //some client that works with callbacks
CompletableFuture<String> request1() {
CompletableFuture<String> result = new CompletableFuture<>();
client.request1(someArguments, (calbackResult) -> result.complete(calbackResult));
return result;
}
}
公共网络管理器实现IRequester{
Client-Client;//使用回调的某个客户端
CompletableFuture request1(){
CompletableFuture结果=新建CompletableFuture();
request1(someArguments,(calbackResult)->result.complete(calbackResult));
返回结果;
}
}
这里的result
承诺在执行回调时,它将提供一个值。在此之前,它将是空的
所以NetworkManager
返回CompletableFuture
,这意味着结果尚未准备好或永远不会准备好(如果回调从未发生)
当Class1.doSomething
尝试从CompletableFuture
获取结果时,当前线程将阻塞,直到值可用或出现超时
这种方法还使
Class1.doSomething
中的代码更加稳定,因为它现在被迫处理超时和缺少结果的问题。下面是一个关于如何使用Observer作为回调等待回调和Thread.sleep来模拟长时间运行的异步任务的示例:
public Object request(){
CompletableFuture<Object> cf = new CompletableFuture<Object>();
runAsync( (o, arg) -> cf.complete(arg) );
try { return cf.get(); }
catch (Exception e) {throw new RuntimeException(e); }
}
public void runAsync(final Observer o){
new Thread( () -> {
try { Thread.sleep(3000L); }
catch (InterruptedException e) { e.printStackTrace(); }
String result = "abc";
o.update(null, result);
} ).start();
}
公共对象请求(){
CompletableFuture cf=新的CompletableFuture();
runAsync((o,arg)->cf.complete(arg));
尝试{返回cf.get();}
catch(异常e){抛出新的RuntimeException(e);}
}
public void runAsync(最终观察者o){
新线程(()->{
试试{Thread.sleep(3000L);}
catch(InterruptedException e){e.printStackTrace();}
字符串结果=“abc”;
o、 更新(空,结果);
}).start();
}
以下是一个示例,介绍如何使用Observer作为回调函数并使用Thread.sleep来模拟长时间运行的异步任务来等待回调:
public Object request(){
CompletableFuture<Object> cf = new CompletableFuture<Object>();
runAsync( (o, arg) -> cf.complete(arg) );
try { return cf.get(); }
catch (Exception e) {throw new RuntimeException(e); }
}
public void runAsync(final Observer o){
new Thread( () -> {
try { Thread.sleep(3000L); }
catch (InterruptedException e) { e.printStackTrace(); }
String result = "abc";
o.update(null, result);
} ).start();
}
公共对象请求(){
CompletableFuture cf=新的CompletableFuture();
runAsync((o,arg)->cf.complete(arg));
尝试{返回cf.get();}
catch(异常e){抛出新的RuntimeException(e);}
}
public void runAsync(最终观察者o){
新线程(()->{
试试{Thread.sleep(3000L);}
catch(InterruptedException e){e.printStackTrace();}
字符串结果=“abc”;
o、 更新(空,结果);
}).start();
}
因为request1()的返回类型是void,所以不能从中返回值。
但是在IRequester的实现类中,您可以传递一个resultObject,
每当执行request1()方法时,它都会将结果存储在result对象中,当需要获取结果时,可以从ResultObject获取结果
class ResultObject{
getResult(); ///return result
setResult(); ///store result
}
public NetworkManager implements IRequester {
private ResultObject callBackResult;
public ResultObject getResult(){
return callBackResult;
}
public void setResult(ResultObject value){
this.callBackResult=value;
}
request1() {
// Create an operation
this.setResult(callProcedure());
// schedule operation
}
request2() {
}
}
由于request1()的返回类型为void,因此无法从中返回值。 但是在IRequester的实现类中,您可以传递一个resultObject, 每当执行request1()方法时,它都会将结果存储在result对象中,当需要获取结果时,可以从ResultObject获取结果
class ResultObject{
getResult(); ///return result
setResult(); ///store result
}
public NetworkManager implements IRequester {
private ResultObject callBackResult;
public ResultObject getResult(){
return callBackResult;
}
public void setResult(ResultObject value){
this.callBackResult=value;
}
request1() {
// Create an operation
this.setResult(callProcedure());
// schedule operation
}
request2() {
}
}
你不能,因为你不知道节点需要多长时间才能为你准备好信息,你需要它们之间的回调你不能,因为你不知道节点需要多长时间才能为你准备好信息,你需要它们之间的回调