[英]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);
}
}
我也嘗試在打印一些String
時run
方法。 但是當它離開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 相關):
您的new JFrame("Chatter")
只是創建了一個新的 JFrame 並且什么都不做。 你必須調用super("Chatter");
調用超級構造函數
嘗試
this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.