Here’s a snippet of a web server that I am currently building…
// …
threadPool = Executors.newCachedThreadPool(); while (true) if(this.isOn) { try { // listen for incoming connection this.clientSocket = serverSocket.accept(); } catch (IOException e) { System.err.println("LOG: >> Accept failed! "); System.exit(1); } // as soon as a connection is established send the socket // with a handler/processor to the thread pool for execution threadPool.execute(new ClientRequestProcessor(clientSocket)); }//…
Please note that the isOn variable is a VOLATILE boolean.
If I turn the if into a while… this code works… but as it is it doesn’t. May I ask why? From a logical point of view both should work, even if I test that flag in an if… am I missing something?!
[Later edit:] By not working I mean… a browser (e.g. firefox) cannot connect, actually it keeps trying but timesout eventually. Again, if I change that if(isOn) into a while(isOn) it works like a charm.
Any suggestions/ideas are more than welcome!!!
P.S. I need this combo “while(true) if/while(test flag) {…}” because the server can be started/stopped from a GUI… so the top level while(true) is kind of needed so I can recheck whether I am on (and thus listening for connections) or if I am off (and don’t really care about incoming connections). Needles to say the event handlers of the GUI can modify the flag at anytime.
A better solution is to close the server socket when you want it to stop and start a new one in a new thread when you want it to start. This way you reject new connections and don’t consume CPU when its not doing anything.
When isOn == true and you turn it false, it will only not accept connections after the next new connection. (Could be any time later) Additionally any client new connections will just wait for the accept to be called (or eventually timeout) You can have up to 50 connections waiting to be accepted by default.
When isOn == false, your thread will busy wait, consuming a CPU. I suggest you put in a little delay such as Thread.sleep(250). This will cut CPU dramatically, but not delay starting again too much.
BTW: