【问题标题】:Java 8: Sonar compliant Server SocketJava 8:Sonar 兼容的服务器套接字
【发布时间】:2020-02-07 04:58:48
【问题描述】:

下面是我的服务器套接字线程的run(),它将作为Executors.newWorkStealingPool().submit(() -> mainServer.run()); 运行并接受客户端连接。它运行良好,但Sonar 抱怨它为Bug 类型Loops should not be infinite (squid:S2189)

    class MainServer {
    private final ServerSocket serverSocket;    
    private final boolean checkClientCerts;
    private static final org.slf4j.Logger LOG = LoggerFactory.getLogger(MainServer.class.getName());
    private final int threadPoolSize;
    private boolean running;
    private ExecutorService executorService;    

 MainServer(int port, boolean checkClientCerts, int threadPoolSize, InetAddress bindAddress) throws IOException {

        LOG.debug("Locating server socket factory for SSL...");
        SSLServerSocketFactory factory = (SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
        LOG.debug("Creating a server socket on port " + port);
        SSLServerSocket serverSocket = (SSLServerSocket) factory.createServerSocket(port, 0, bindAddress);        
        this.checkClientCerts = checkClientCerts;
        this.threadPoolSize = threadPoolSize;
    }

    void run() {
        running = true;
        DefaultThreadFactory threadFactory = new DefaultThreadFactory("SSLHandshake");
        executorService = new ShutdownThreadPoolExecutor(threadPoolSize,threadFactory);

        while (running) {
            Socket clientSocket;

            try {
                clientSocket = serverSocket.accept();
                MainServerHandshakeThread handshakeThread = new MainServerHandshakeThread(clientSocket, this);                
                executorService.submit(handshakeThread);

            } catch (IOException ex) {
                LOG.error("Error accepting connection",ex);
            }

        }
    }

    public void shutdown() {
        LOG.info("Stopping main server...");
        running = false;
        try {
            if (serverSocket!=null) {
                serverSocket.close();
            }
        } catch(IOException ex) {
            LOG.debug("Failed to close socket",ex);
        }

        executorService.shutdown();
        try {
            if (!executorService.awaitTermination(500, TimeUnit.MILLISECONDS)) {
                executorService.shutdownNow();
            } 
        } catch (InterruptedException e) {
            executorService.shutdownNow();
        }             
        LOG.info("Main server stopped...");
    }
}

有人可以帮我如何优化上述代码块以消除声纳投诉吗?

【问题讨论】:

  • 好吧,为什么不应用警告所说的内容并使while (running) {...} 循环无限?您永远不会更改您共享的代码中的 running 变量。
  • @Fureeish 用完整的代码更新了问题,mainServer 将以Executors.newWorkStealingPool().submit(() -> mainServer.run()); 运行,并且在应用程序停止时通过调用shutdown() 来停止
  • running 标记为volatile 是否可以消除错误?
  • @Fureeish 是的,令人惊讶地将running 标记为volatile 摆脱了这个错误,它背后的魔力是什么?
  • 请看我的回答,我试图简要解释正在发生的事情并提供一些额外的阅读。

标签: java sockets sonarqube-scan


【解决方案1】:

将您的running 标记为volatile

volatile 将变量可见,其他线程可以更改1。这意味着优化器(或代码分析器,如 SonarQube)不能假设其他线程修改此类变量。在您的示例中,这两个都可以假设running 从不更改,从而将您的代码标记为具有无限循环。类似的例子可以在in this answer找到。

你应该将你的变量标记为volatile,如果它们可以被其他线程访问和修改。


1已由 user207421 更正。

【讨论】:

  • 它已经对其他线程可见。 volatile 表示它可以被其他线程更改
猜你喜欢
  • 1970-01-01
  • 2013-02-11
  • 2011-11-28
  • 2013-12-19
  • 1970-01-01
  • 1970-01-01
  • 2015-06-06
  • 2013-04-04
  • 1970-01-01
相关资源
最近更新 更多