这是我当前正在构建的Web服务器的片段...


  // ...

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));
        }

  
  // ...


请注意,isOn变量是VOLATILE布尔值。

如果我将if转换为一会儿...此代码可以正常工作...但事实并非如此。请问为什么?从逻辑的角度来看,即使我在if ...中测试该标志,两者都应该起作用。

[稍后编辑:]我的意思是不工作,因为浏览器(例如firefox)无法连接,实际上它一直在尝试,但最终超时。同样,如果我将if(isOn)更改为while(isOn),它的工作原理就像是一种魅力。

任何建议/想法都非常欢迎!!!

附言我需要这个组合“ while(true)if / while(test flag){...}”,因为可以从GUI启动/停止服务器...所以顶层需要while(true),所以我可以重新检查我是打开(因此正在监听连接)还是关闭(并且实际上并不关心传入的连接)。需要说GUI的事件处理程序可以随时修改标志的针。

最佳答案

更好的解决方案是在要停止时关闭服务器套接字,并在希望启动时在新线程中启动新套接字。这样,您拒绝新的连接,并且在不执行任何操作时不会消耗CPU。

当isOn == true且将其设置为false时,它将仅在下一个新连接之后不接受连接。 (可能在以后的任何时间)另外,任何客户端新连接将仅等待调用接受(或最终超时)。默认情况下,您最多可以有50个连接等待被接受。

当isOn == false时,您的线程将忙于等待,消耗CPU。我建议您稍加延迟,例如Thread.sleep(250)。这将大大减少CPU的使用时间,但不会延迟太多启动时间。

顺便说一句:


如果遇到异常,则应注销/打印出来。否则,当它失败时,您将不知道为什么。
如果accept失败,则可能是该进程没有文件,因此您不希望它死掉,从而杀死所有现有连接。

09-04 05:02