Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/11.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实现_Java_Algorithm_Design Patterns - Fatal编程技术网

处理回调消息的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() {

}
}


你不能,因为你不知道节点需要多长时间才能为你准备好信息,你需要它们之间的回调你不能,因为你不知道节点需要多长时间才能为你准备好信息,你需要它们之间的回调