I have two while conditions, one inside the other, with booleans to control them. Basically, one is for terminating a share and the other is to listen for a connection. A user can select to disable a share, and in this case, the server stops listening but it won’t terminate. If a user selects to terminate then both booleans are set to false and the cycle ends.
This is my code:
public void run() {
while (!terminate) {
while (listening) {
try {
// accept connection -> create a new thread for each client
ClientServerShareInstance clientServerShareInstance = new ClientServerShareInstance(serverSocket.accept(), ui);
Thread clientServerThread = new Thread(clientServerShareInstance);
clientSockets.add(clientServerShareInstance);
connectedClients++;
clientServerThread.start();
} catch (IOException ex) {
}
}
}
}
public void closeAllClientConnections() {
for (Iterator it = clientSockets.iterator(); it.hasNext();) {
ClientServerShareInstance clientServerShareInstance = (ClientServerShareInstance) it.next();
clientServerShareInstance.closeAllConnections();
it.remove();
}
try {
this.serverSocket.close();
} catch (IOException ex) {}
this.setActive(false);
this.connectedClients = 0;
}
public void openConnection() {
try {
serverSocket = new ServerSocket(portNumber, 0, Inet4Address.getLocalHost());
setActive(true);
} catch (IOException ex) {}
}
}
The closeAllClientConnections() method disables a share (does not terminate it), and the openConnection() reenables that share.
The problem is, if I disable a share, it should just loop the terminate while cicle indefinitely, testing the value of listening. When I set listening to true, it should re-enter that second while loop and start listening again, because I do open the server socket (although it’s not related to that, I’m just saying it has to be initialized again because I close it when I disable the share). However, after disabling, it never renters the listening loop, even when openConnection() is called.
Anyone know what’s wrong here?
There’s not enough code shown to show any errors. But here are some comments that might help.
Both the
shutdownandlisteningbooleans need to bevolatile. Any fields shared between threads need to be somehow synchronized otherwise changes to their values will not be seen by other threads.serverSocketwill also need to bevolatilesince it seems to be created by the caller ofopenConnection()but consumed in thewhileloop. You might consider just setting active to the true inopenConnection()and haveserverSocketmanaged entirely by the accept thread.clientSocketslooks to be a collection. That will need to be a synchronized connection since, again, it looks like it is accessed by multiple threads. Again, a better pattern would be for thecloseAllClientConnections()call to just set a boolean and the thread itself would do the closing. That removes any race conditions around using the collections, etc..Looks to be that if you are
! terminatingthat your accept thread will spin. At the very least you should put someThread.sleep(100)or something to slow it down. A wait/notify would even be better.It is important to realize that it is not just about what happens “at the same time” in a threaded program. It is also about memory caching. The accept thread could have added something to the
clientSocketsArrayList1a minute ago and another thread may not see those changes if the list is not synchronized somehow. Even worse is the prospect that certain portions of theArrayListmay have been updated in memory but not others which might cause an exception. To get a synchronized collection, you should create yourArrayListlike:Sounds like you should read some of the documentation about why synchronization is necessary: