簡體   English   中英

線程。 停止服務器

[英]Threads. Stopping 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);
    }


}

我也嘗試在打印一些Stringrun方法。 但是當它離開run方法時,程序仍在工作。 有什么建議么? 提前致謝。

我還嘗試按以下方式實現run()

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

最后它true做到了 output 。

您是否嘗試過將您的online財產聲明為volatile

private volatile boolean online = true;

如果您沒有將屬性聲明為volatile ,JIT 編譯器可以假定您的 boolean 屬性不會被另一個線程更改。 所以它可以優化你的運行方法

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

也許你這里有另一個問題(Swing 相關):

  1. 您的new JFrame("Chatter")只是創建了一個新的 JFrame 並且什么都不做。 你必須調用super("Chatter"); 調用超級構造函數

  2. 嘗試

    this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM