java - 多线程/ volatile 变量/条件/循环的特殊行为(Java)

标签 java multithreading loops volatile conditional-statements

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

// ...

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 boolean 值。

如果我把 if 变成 while...这段代码可以工作...但事实上它不起作用。请问为什么?从逻辑的角度来看,两者都应该有效,即使我在 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,但不会过多地延迟重新启动。

顺便说一句:

  • 如果出现异常,您应该将其记录/打印出来。否则当失败时你将不知道为什么。
  • 如果接受失败,可能是该进程没有文件,因此您不希望它直接终止,从而终止所有现有连接。

关于java - 多线程/ volatile 变量/条件/循环的特殊行为(Java),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4602416/

相关文章:

c - 线程同步——什么时候终止线程?

java - 使用 JavaFX 任务正确执行多线程和线程池

java - parking 模拟无限循环危机

javascript for (i = 0; i < XXX.length; i++) -> 长度问题

java - 需要从启动屏幕重定向到网页

java - java中的notifyAll()会释放其他类的线程吗?

java - WebView 不打开 android 默认视频播放器?

php - 在 php 中循环 - 创建不同的卷号

java - Android Studio写入.properties文件

java - 使用 android NativeActivity 时从 SoftInput 接收所有 unicode 字符