java make a method wait for a response of another

2019-06-11 07:55发布

问题:

In my program, I connect to an interpreter process for another language. I need the program sometimes to ask the interpreter several things and use it's response.

The process is stored in a IProcess variable and the communication is done via the IStreamsProxy of the process. to recieve the response, I added an IStreamListener to the IStreamsProxy.

However, when I write to the IStreamsProxy (with the write() method), I need the code to wait for the response, e.g. the streamAppend-method of the listener to be called.

I tried to use the wait() and notify() method, but I don't know on what objects I should call them.

The query class which makes the communication calls a method like this:

/**
 * Sends a command to the interpreter. Makes the current thread wait for an answer of the interpreter.
 * @throws IOException 
 */
private synchronized void send(String command) throws IOException{
    this.s48Proxy.write(command);
    try {
        System.out.println("waiting for reply");
        this.wait();
    } catch (InterruptedException e) {
        System.out.println("interruption exception: "+e.getMessage());
    }
}

and the listener:

private class Listener implements IStreamListener {

    private Query query;

    public Listener(Query query) {
        super();
        this.query = query;
    }

    @Override
    public void streamAppended(String arg0, IStreamMonitor arg1) {
        System.out.println("got interpreter answer");
        query.setCurrentOutput(arg0.substring(0, arg0.lastIndexOf("\n")).trim());
        query.notify();
    }
}

The streamAppend() method calls the notify()-method on the query class. However, this does not work. "Waiting for reply" is the last response I get.

How can I do this? Or are there any other methods I could use to achieve this automatically?

回答1:

You could use Object#wait & Object#notifiy.

// @ IStreamsProxy
synchronized( someMonitor ) {
  someMonitor.wait( /* time? */ );
}

// @ Listener
synchronized( someMonitor ) {
  someMonitor.notify();
}

-> Javadoc Link



回答2:

Use a semaphore like boolean waitingForResponse. Set this to true when you make your call, then go into

while(waitingForResponse){ sleep(99) //should be your average response time from your call }

In your listener, set waitinForResponse to false.