我正在编写一个套接字客户端,用于与网络服务进行交互。目前因为我想支持异步读取和写入,我正在线程输出流和一个套接字的输入流,但我想知道是否有更好的方法来执行此操作。我看过Java NIO并没有留下深刻的印象,我也看了Mina,但是想知道是否有人有更好的想法。
感谢。
答案 0 :(得分:1)
我用于异步通信的技术是使用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;
}
}
答案 1 :(得分:0)