Java 8:Sonar 兼容服务器套接字

Java 8: Sonar compliant Server Socket

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

Bug
    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...");
    }
}

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

将您的 running 标记为 volatile

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

如果其他线程可以访问和修改变量,则应将变量标记为 volatile


1user207421 更正。