如何在关闭的GUI(java)上停止运行无限循环的程序

如何在关闭的GUI(java)上停止运行无限循环的程序,java,swing,sockets,termination,windowlistener,Java,Swing,Sockets,Termination,Windowlistener,我有一个使用套接字进行服务器/客户端通信的简单程序。 服务器类包含run()方法,此方法有无限循环等待套接字接受 无论如何,我在构造函数中编写了一个代码,在关闭时终止处理 this.addWindowListener(new java.awt.event.WindowAdapter() { @Override public void windowClosing(java.awt.event.WindowEvent windowEvent) { System.ou

我有一个使用套接字进行服务器/客户端通信的简单程序。 服务器类包含
run()
方法,此方法有无限循环等待套接字接受

无论如何,我在构造函数中编写了一个代码,在关闭时终止处理

 this.addWindowListener(new java.awt.event.WindowAdapter() {
    @Override
    public void windowClosing(java.awt.event.WindowEvent windowEvent) {
        System.out.println("Close operation server done");
        toClient.println("Bye");
        closeStreams();
        socket = null;
        serverSocket = null;
        System.exit(0);
    }
});
当我阅读
窗口关闭(WindowEvent e)
的API时,它说:

当窗口处于关闭过程中时调用。结束 此时可以重写操作

当窗口处于关闭过程中时,它会显示。但是run()方法中的循环仍然获得控制权,并且由于程序的逻辑而不会完成,因此窗口不会关闭(实际上GUI已关闭),但处理仍在幕后进行

更新:

run()
方法:

public void run()
{
    try
    {
        while (true)
        {
            idle = true;
            System.out.println("System is running");
            socket = serverSocket.accept();
            System.out.println("Client accepted on server side");
            openStreams();
            toClient.println("Hello: server is connected " + serverAddress.getLocalHost().toString());
            processClient();
            //   closeStreams();
        }
    } catch (Exception e)
    {
        System.out.println("Error accepting server " + e);
    }
}
 public void processClient() throws IOException
    {
        System.out.println("Porcessing start");
        String line = fromClient.readLine();
        try
        {
            while (!(line.equals("Bye")))
            {
                textToReceive.append("He: " + line + newline);
                line = fromClient.readLine();
            }
            closeStreams();

        } catch (IOException ex)
        {
            System.out.println("Error reading from client " + ex);
        }
    }
processClient()
方法:

public void run()
{
    try
    {
        while (true)
        {
            idle = true;
            System.out.println("System is running");
            socket = serverSocket.accept();
            System.out.println("Client accepted on server side");
            openStreams();
            toClient.println("Hello: server is connected " + serverAddress.getLocalHost().toString());
            processClient();
            //   closeStreams();
        }
    } catch (Exception e)
    {
        System.out.println("Error accepting server " + e);
    }
}
 public void processClient() throws IOException
    {
        System.out.println("Porcessing start");
        String line = fromClient.readLine();
        try
        {
            while (!(line.equals("Bye")))
            {
                textToReceive.append("He: " + line + newline);
                line = fromClient.readLine();
            }
            closeStreams();

        } catch (IOException ex)
        {
            System.out.println("Error reading from client " + ex);
        }
    }
如何正确地强制程序运行

更新2:整个工作服务器类:

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.io.*;
import java.net.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.*;

/**
 *
 * @author S
 */
public class ChatServer extends JFrame
{

    private InetAddress serverAddress;
    private Socket socket;
    private ServerSocket serverSocket;
    private InputStream is;
    private OutputStream os;
    private BufferedReader fromClient;
    private PrintWriter toClient;
    private JButton send;
    private JPanel uperPanel;
    private JPanel midPanel;
    private JPanel downPanel;
    private JTextArea textToSend;
    private JTextArea textToReceive;
    private JLabel addressL;
    private final int port = 5555;
    private boolean idle = false;
    private int timeout = 3000;
    public static String newline = System.getProperty("line.separator");

    private ChatServer()
    {
        this.setGUI();
        this.setVisible(true);
        try
        {
            serverSocket = new ServerSocket(port);
            this.run();
        } catch (IOException ex)
        {
            Logger.getLogger(ChatServer.class.getName()).log(Level.SEVERE, null, ex);
        }

        this.addWindowListener(new java.awt.event.WindowAdapter()
        {
            @Override
            public void windowClosing(java.awt.event.WindowEvent windowEvent)
            {
                idle = true;
                closeStreams();
                socket = null;
                serverSocket = null;
                System.exit(0);
            }
        });
    }

    public void run() throws IOException
    {
        try
        {
            while (true)
            {
                System.out.println("System is running");
                socket = serverSocket.accept();
                System.out.println("Client accepted on server side");
                openStreams();
                toClient.println("Hello: server is connected " + serverAddress.getLocalHost().toString());
                processClient();
                //   closeStreams();
            }
        } catch (java.net.SocketTimeoutException ee)
        {

            closeStreams();
            System.out.println(ee);


        } catch (Exception e)
        {
            System.out.println("Error accepting server " + e);
        }

    }

    public void processClient() throws IOException
    {
        System.out.println("Porcessing start");
        String line = fromClient.readLine();
        try
        {
            while (!(line.equals("Bye")))
            {
                textToReceive.append("He: " + line + newline);
                line = fromClient.readLine();
            }
            closeStreams();

        } catch (IOException ex)
        {

            System.out.println("Error reading from client " + ex);

        }
    }

    private void setGUI()
    {

        this.setSize(375, 314);


        send = new JButton("send");

        try
        {
            addressL = new JLabel("My Server address: " + serverAddress.getLocalHost().toString()
                    + "  Port: " + this.port);
        } catch (Exception e)
        {
            System.out.println("Unknown Host problem " + e);
        }

        textToReceive = new JTextArea(12, 30);
        textToReceive.setLineWrap(true);
        JScrollPane recievedScrolledText = new JScrollPane(textToReceive);
        recievedScrolledText.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
        textToReceive.setEditable(false);


        textToSend = new JTextArea(3, 25);
        textToSend.setLineWrap(true);
        JScrollPane sentScrolledText = new JScrollPane(textToSend);
        sentScrolledText.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
        textToSend.setEditable(true);

        uperPanel = new JPanel();
        midPanel = new JPanel();
        downPanel = new JPanel();

        uperPanel.add(addressL);


        midPanel.add(recievedScrolledText);
        downPanel.add(sentScrolledText);
        downPanel.add(send);

        Container c = getContentPane();
        c.setLayout(new BorderLayout());
        c.add(uperPanel, "North");
        c.add(midPanel, "Center");
        c.add(downPanel, "South");

        send.addActionListener(new ButtonWatch());
        textToSend.addKeyListener(new KeyWatch());
    }

    private void openStreams() throws IOException
    {

        is = socket.getInputStream();
        fromClient = new BufferedReader(new InputStreamReader(is));
        os = socket.getOutputStream();
        toClient = new PrintWriter(os, true);
        System.out.println("open stream is open on server");
    }

    private void closeStreams()
    {
        try
        {

            if ((toClient != null) && (os != null)
                    && (fromClient != null) && (is != null)
                    && (fromClient != null) && (socket != null))
            {
                toClient.close();
                os.close();
                fromClient.close();
                is.close();
                socket.close();
            }


        } catch (IOException ex)
        {
            System.out.println("Problem closing streams " + ex);
        }
    }

    private class KeyWatch extends KeyAdapter
    {

        public void keyPressed(KeyEvent e)
        {
            if (e.getKeyCode() == KeyEvent.VK_ENTER)
            {
                String line = textToSend.getText();
                textToSend.setText("");
                toClient.println(line);
                textToReceive.append("You: " + line + newline);
            }
        }

        public void keyReleased(KeyEvent e)
        {
            if (e.getKeyCode() == KeyEvent.VK_ENTER)
            {
            }
        }

        public void keyTyped(KeyEvent e)
        {
            if (e.getKeyCode() == KeyEvent.VK_ENTER)
            {
            }
        }
    }

    private class ButtonWatch implements ActionListener
    {

        @Override
        public void actionPerformed(ActionEvent e)
        {
            Object buttonPressed = e.getSource();

            if (buttonPressed == send)
            {
                String line = textToSend.getText();
                textToSend.setText("");
                toClient.println(line);
                textToReceive.append("You: " + line + newline);

                System.out.println("send to client " + line);
            }

        }
    }

    public static void main(String[] args)
    {
        ChatServer s = new ChatServer();
        s.setVisible(true);
    }
}

现在,如何在关闭后终止它。

-好吧,最好使用
执行器来跨越线程

-然后使用
cancel(true)
submit()
方法中断此特定线程


-如果您想直接使用
线程
,则可以使用
中断()
中断()
方法中断
线程
将服务器循环更改为非无限循环

volatile boolean runFlag = true;
while (runFlag) {
  //do server stuff
}
并让关闭方法标记服务器停止

this.addWindowListener(new java.awt.event.WindowAdapter() {
  @Override
  public void windowClosing(java.awt.event.WindowEvent windowEvent) {
    System.out.println("Close operation server done");
    toClient.println("Bye");
    closeStreams();
    runFlag = false;
  }
});

您可能希望将关闭流的内容移动到主服务器循环之后,以便完成正在进行的任何内容,并且不会中断当前正在进行的任何内容。

演示您的循环。通常,正确的方法是保持对运行循环的线程的引用,并调用
Thread.interrupt
,其中
run
方法定期检查
Thread.interrupted()
状态。infiny循环是在未显示的代码行中产生的,我打赌代码行是第57行。或/和875.,为了获得更好的帮助,请尽早发布SSCCE,演示您的上午问题,简短、可运行、可编译、关于关闭套接字和空JFrame,否则这里的一切都是黑暗的,与这里的答案相反,大多数(使用API中实现的方法关闭)工作线程和连接、Socker、RMI,眼镜蛇如果是异步的,那么就没有担保对象依赖的,隐藏JFrame,然后使用terminate/close/expire/whatever执行一些操作,但是默认情况下套接字没有问题,OPs错误没有发布也没有描述我更新我的问题,如果你知道如何使其终止,请告诉我。感谢可能的副本