I wrote a game in Java with a client and server side using sockets and data input/output streams. The server side sometimes needs to send a message to all users in a "for" loop, but since writing to a socket can block I created a thread for each user that sends him messages (as well as another thread for each user that listens to incoming messages). The sending thread is built on this idea:
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);
}
}
Unfortunately the run() method is constantly running, so I'd like to insert a sleep command, to achieve something like this:
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();
}
}
But this may cause the thread to go to sleep when there are messages to send, for example when the write() method is called just after the run() method made the isEmpty() check, that returned true, but has not yet started to sleep. I really can't think of a way to avoid this problem with sleep(0), has anyone got a idea? Or am I going the wrong way about this?
Thanks a bunch.