线程。停止服务器

时间:2019-09-23 14:39:36

标签: java multithreading server

最近我正在做多线程聊天应用程序。现在我在服务器上挣扎。我正试图通过引入新字段online来停止服务器,但这无济于事。



import view.ChatHub;

import java.io.IOException;
import java.io.PrintWriter;
import java.lang.reflect.Array;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Set;
import java.util.HashSet;
import java.util.Scanner;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class ChatServer extends Thread {
    // All client names, so we can check for duplicates upon registration.
    private static Set<String> names = new HashSet<>();
    // The set of all the print writers for all the clients, used for broadcast.
    private static Set<PrintWriter> writers = new HashSet<>();
    private ChatHub frame;
    private int port;
    private boolean online;
    private ExecutorService pool;

    public ChatServer(int port) throws IOException {
        System.out.println("The chat server is running...");
        this.frame = new ChatHub(this);
        this.port = port;
        this.online = true;
        this.pool = Executors.newFixedThreadPool(500);
        this.start();
    }

    @Override
    public void run() {
        while (this.online) {
            try (ServerSocket listener = new ServerSocket(this.port)) {
                this.pool.execute(new Handler(listener.accept(), this.names, this.writers));
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public void stopChatServer() {
        this.pool.shutdown();
        this.online = false;
    }


    public Set<String> getNames() {
        return this.names;
    }

    public Set<PrintWriter> getWriters() {
        return this.getWriters();
    }

    public ChatHub getFrame() {
        return this.frame;
    }

    public int getPort() {
        return this.port;
    }

}

这里我要关闭服务器:


import Client.ChatClient;
import Server.ChatServer;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;


public class ChatHub extends JFrame{
    JTextField textField;
    JTextArea messageArea;

    public ChatHub(ChatServer server) {
        new JFrame("Chatter");
        this.textField = new JTextField(50);
        this.messageArea = new JTextArea(16,50);
        this.textField.setEditable(true);
        this.messageArea.setEditable(false);
        this.getContentPane().add(this.textField, BorderLayout.SOUTH);
        this.getContentPane().add(new JScrollPane(this.messageArea), BorderLayout.CENTER);
        this.pack();
//        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent we) {
                server.stopChatServer();
            }
        });
        this.setVisible(true);
    }

    public void appendMessage(String line) {
        messageArea.append(line + "\n");
    }

    public JTextField getTextField() {
        return this.textField;
    }

    public JTextArea getMessageArea() {
        return this.messageArea;
    }

    public void nameAccepted(String line) {
        this.setTitle("Chatter - " + line.substring(13));
        textField.setEditable(true);
    }


}

我还尝试使用方法run,而只打印一些String。但是当它离开run方法时,程序仍在工作。有什么建议么?预先感谢。

我还尝试如下实现run()

@Override
    public void run() {
        while (this.online) {
            System.out.println("Some String");
        }
        System.out.println(this.isAlive() + "\n");
    }

它最终会输出true

2 个答案:

答案 0 :(得分:0)

您是否尝试将online属性声明为volatile

private volatile boolean online = true;

如果您未将属性声明为volatile,则JIT编译器可以假定您的布尔属性不会被另一个线程更改。因此,它可能会将您的运行方法优化为

public void run() {
    if (!online)
        return;
    while(true) {
        try(/*...*/) {
           // ...
        } catch(/*...*/) {
           // ...
        }
    }
}

答案 1 :(得分:0)

也许您在这里还有另一个问题(与Swing相关):

  1. 您的new JFrame("Chatter")仅创建一个新的JFrame,并且对此不执行任何操作。您必须调用super("Chatter");才能调用超级构造函数

  2. 尝试

    this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE)