现在我已经学会了很多关于同步的教程,但现在我的头在旋转。我从来没有真正了解它:(。
我有一个Java服务器( MainServer ),当客户端连接时,它将使用DataOutputStream创建一个新线程( ServerThread )。
客户端与 ServerThread 进行对话,并且 ServerThread 进行响应。 MainServer 会不时地使用每个 ServerThread的 DataOutputStream对象向所有客户端分发消息。
我可以肯定,我的问题时不时地是因为 MainServer 和 ServerThread 都试图同时向客户端发送内容。因此,我需要锁定DataOutputStream对象。对于我的一生,我再也无法理解这个概念。我读的每个例子都令人困惑。
处理此问题的正确方法是什么?
ServerThread的发送到客户端方法:
public void replyToOne(String reply){
try {
commandOut.writeUTF(reply);
commandOut.flush();
} catch (IOException e) {
logger.fatal("replyToOne", e);
}
logger.info(reply);
}
MainServer分发给所有客户端的方法:
public static void distribute(String broadcastMessage){
for (Map.Entry<String, Object[]> entry : AccountInfoList.entrySet()) {
Object[] tmpObjArray = entry.getValue();
DataOutputStream temporaryCOut = (DataOutputStream) tmpObjArray[INT_COMMAND_OUT]; //can be grabbed while thread is using it
try {
temporaryCOut.writeUTF(broadcastMessage);
temporaryCOut.flush();
} catch (IOException e) {
logger.error("distribute: writeUTF", e);
}
logger.info(broadcastMessage);
}
}
我在想我的 ServerThread 类中应该有类似的内容。
public synchronized DataOutputStream getCommandOut(){
return commandOut;
}
真的那么简单吗?我知道这可能已经被提出并得到了回答,但是如果没有个人的帮助,我似乎仍然无法解决。
最佳答案
如果这是我.....
我在每个客户端线程上都有一个 LinkedBlockingQueue
。然后,每次客户端线程在套接字上有空闲时间时,它都会检查队列。如果队列中有消息要发送,它将发送它。
然后,如果需要,服务器可以仅将项目添加到该队列中,并且当连接具有一定空间时,将发送该连接。
添加队列,在ServerThread上有一个类似以下方法的方法:
addBroadcastMessage(MyData data) {
broadcastQueue.add(data);
}
然后,在套接字端,有一个循环,上面有一个超时块,这样,如果空闲,它就会从套接字中退出,然后:
while (!broadcastQueue.isEmpty()) {
MyData data = broadcastQueue.poll();
.... send the data....
}
到此为止。
LinkedBlockingQueue
将为您管理锁定和同步。