我使用套接字和数据输入/输出流用 Java 编写了一个带有客户端和服务器端的游戏。服务器端有时需要在“for”循环中向所有用户发送消息,但由于写入套接字可能会阻塞我为每个向他发送消息的用户创建了一个线程(以及为每个用户监听的另一个线程)传入消息)。发送线程是建立在这个想法上的:
private ArrayList<Object> messages = new ArrayList<Object>(),
newMessages = new ArrayList<Object>();
public void run() {
while (true) {
for (Object message: messages) {
try {
if (message instanceof Byte)
out.writeByte((Byte)message);
else if (message instanceof Boolean)
out.writeBoolean((Boolean)message);
else if (message instanceof String)
out.writeUTF((String)message);
else if (message instanceof Integer)
out.writeInt((Integer)message);
else if (message instanceof Long)
out.writeLong((Long)message);
} catch (IOException e) {}
}
synchronized (newMessages) {
messages.clear();
messages.addAll(newMessages);
newMessages.clear();
}
}
}
public void write(Object message) {
synchronized (newMessages) {
newMessages.add(message);
}
}
不幸的是,run() 方法一直在运行,所以我想插入一个 sleep 命令,以实现如下效果:
private ArrayList<Object> messages = new ArrayList<Object>(),
newMessages = new ArrayList<Object>();
public void run() {
while (true) {
try {
if (messages.isEmpty() && newMessages.isEmpty())
sleep(0);
} catch (InterruptedException e) {}
for (Object message: messages) {
try {
if (message instanceof Byte)
out.writeByte((Byte)message);
else if (message instanceof Boolean)
out.writeBoolean((Boolean)message);
else if (message instanceof String)
out.writeUTF((String)message);
else if (message instanceof Integer)
out.writeInt((Integer)message);
else if (message instanceof Long)
out.writeLong((Long)message);
} catch (IOException e) {}
}
synchronized (newMessages) {
messages.clear();
messages.addAll(newMessages);
newMessages.clear();
}
}
}
public void write(Object message) {
synchronized (newMessages) {
newMessages.add(message);
interrupt();
}
}
但这可能会导致线程在有消息要发送时进入睡眠状态,例如当 write() 方法在 run() 方法进行 isEmpty() 检查后调用时,返回 true,但尚未启动睡觉。我真的想不出一种方法来避免 sleep(0) 的这个问题,有人知道吗?还是我在这件事上走错路了?
谢谢一堆。