Java 8: совместимый с Sonar серверный сокет - PullRequest
1 голос
/ 09 октября 2019

Ниже указан мой 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...");
    }
}

Может кто-нибудь помочь мне, как оптимизировать вышеуказанный блок кода, чтобы избавиться от жалобы Sonar?

1 Ответ

1 голос
/ 09 октября 2019

Отметьте running как volatile.

volatile помечает переменную видимую для как переменную 1 с помощью другие темы . Это означает, что оптимизатор (или анализатор кода, такой как SonarQube) не может предполагать, что другие потоки не изменяют такую ​​переменную. В вашем примере оба из них могут предположить, что running никогда не изменит , что помечает ваш код как бесконечный цикл. Подобный пример можно найти в этом ответе .

Вы должны пометить свои переменные как volatile, если они могут быть доступны и изменены другими потоками.


1 Исправлено user207421 .

...