Техника, которую я использовал для асинхронной связи, заключалась в использовании ExecutorService. В моем примере ниже, служба будет выполнять FutureTask, которая будет ждать следующей строки. Тем временем сервер может продолжать выполнять другие задачи и периодически опрашивать читателя, чтобы узнать, был ли получен результат.
Для написания вы можете реализовать аналогичный FutureTask.
Примечание. Вам не нужно расширять функциональность существующего Stream / Reader / Writer, как я. Это был просто исходный код, который мне пригодился
public class SocketStringReader extends BufferedReader {
/**
* Internal buffer used for asynchronous reads
*/
private HashMap<String, String> buf = null;
/**
* Waiting status used for asynchronous reads
*/
private boolean waiting = false;
/**
* Shared ExecutorService for asynchronous reads
*/
private static ExecutorService executor = Executors.newCachedThreadPool();
/**
* Constructor here to pacify Java
* @param in The InputStream to be used as the underlying stream
*/
public SocketStringReader(InputStream in) {
super(new InputStreamReader(in));
}
@Override
public HashMap<String, String> readHashMap() throws IOException,
ClassNotFoundException {
if (buf != null) {
HashMap<String, String> resp = new HashMap<String, String>(buf);
buf = null;
return resp;
}
return stringToHashMap(this.readLine());
}
/**
* Parses a string and converts it to a HashMap
* @param map A String object of the format "{key=value, key=value, ...}"
* that is parsed into a HashMap
* @return The parsed HashMap
*/
public static HashMap<String, String> stringToHashMap(String map) {
// take the string apart
String[] split = map.split("[={},]");
HashMap<String, String> result = new HashMap<String, String>();
for (int i = 1; i < split.length; i += 2) {
result.put(split[i].trim(), split[i + 1].trim());
}
logger.debug("new incoming HashMap: " + result.toString());
return result;
}
/**
* Returns the availability of the input stream
* @return The number HashMap objects in the internal buffer
*/
public int getAvailable() throws IOException {
return (buf == null) ? 0 : 1;
}
@Override
public HashMap<String, String> readHashMapAsync() throws IOException,
ClassNotFoundException {
//Check internal buffer
if (buf != null) {
HashMap<String, String> temp = new HashMap<String, String>(buf);
buf = null;
return temp;
} else {
//Do future crap? or nothing perhaps...
if (!waiting) {
waiting = true;
FutureTask<HashMap<String, String>> future = new FutureTask<HashMap<String, String>>(
new Callable<HashMap<String, String>>() {
@Override
public HashMap<String, String> call() throws Exception {
buf = stringToHashMap(readLine());
logger.debug("Read object with sessionid: " + buf.get("sessionid"));
waiting = false;
return null;
}
});
executor.execute(future);
}
}
return null;
}
}