Потоки.Остановка сервера - PullRequest
0 голосов
/ 23 сентября 2019

Недавно я занимался многопоточным приложением чата.Сейчас я борюсь с сервером.Я пытаюсь остановить сервер, введя новое поле 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 голосов
/ 27 сентября 2019

Возможно, у вас есть еще одна проблема (Swing Related):

  1. Ваш new JFrame("Chatter") просто создает новый JFrame и ничего с ним не делает.Вы должны позвонить super("Chatter");, чтобы вызвать супер-конструктор

  2. Попробуйте

    this.setDefaultCloseOperation (JFrame.DISPOSE_ON_CLOSE)

0 голосов
/ 23 сентября 2019

Вы пытались объявить свое свойство online как volatile?

private volatile boolean online = true;

Если вы не объявите свойство как volatile, JIT-компилятор может предположить, что ваше логическое свойство не будетбыть изменен другим потоком.Так что это может оптимизировать ваш метод запуска до

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