Java 即使在其他线程中启动,帧也会冻结

Java 即使在其他线程中启动,帧也会冻结,java,multithreading,swing,freeze,Java,Multithreading,Swing,Freeze,我希望在我的程序与其他播放器连接时显示一个帧。但是,即使框架在他自己的线程中运行,当Serversocket尝试连接时,它仍然处于冻结状态。我怎样才能防止它结冰 public static boolean connectH(String check, String data, int k){ ServerSocket serverSocket = null; Socket clientSocket = null; PrintWriter out = null; B

我希望在我的程序与其他播放器连接时显示一个帧。但是,即使框架在他自己的线程中运行,当Serversocket尝试连接时,它仍然处于冻结状态。我怎样才能防止它结冰

public static boolean connectH(String check, String data, int k){
    ServerSocket serverSocket = null;
    Socket clientSocket = null;
    PrintWriter out = null;
    BufferedReader in = null;
    message = "waiting for someone to connect to your " + check + "-game";
    th = new Thread(){
        @Override
        public void run() {
            c = new Canceler(message);
        }
    };
    th.start();
    try {
        serverSocket = new ServerSocket(Integer.parseInt(data));
    } catch (IOException e) {
        JOptionPane.showMessageDialog(null, "Could not listen on port: " + data);
        Main.m.finishgame(-1);
    }


    try {
        clientSocket = serverSocket.accept();
    } catch (IOException e) {
        System.err.println("Accept failed.");
        System.exit(1);
    }

    try {
        out = new PrintWriter(clientSocket.getOutputStream(), true);
    } catch (IOException e) {
        e.printStackTrace();
    }
    try {
        in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
    } catch (IOException e) {
        e.printStackTrace();
    }
    try {
        if (in.readLine().equals(check)){
            out.println(k);
            c.remove();
            return true;
        }else{
            out.println(String.valueOf(-1));
            c.remove();
            return false;
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
    c.remove();
    return false;
}

也许这个示例小程序可以帮助您开始

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.InvocationTargetException;
import java.net.ServerSocket;
import java.net.Socket;

import javax.swing.JApplet;
import javax.swing.JButton;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;

public class Example extends JApplet
{
    private JButton _jButtonStartGameServer;
    private boolean _isStarted = false;
    private GameServer _gameServer = null;
    private JTextArea _jTextArea;
    private Thread _gameServerThread = null;
    private boolean _initialized = false;

    public Example()
    {
        System.out.println("ctor...");
    }

    private void initComponents()
    {
        if (_initialized)
        {
            return;
        }

        _jButtonStartGameServer = new JButton("Start Game Server");
        _jButtonStartGameServer.addActionListener(new ActionListener()
        {
            public void actionPerformed(ActionEvent e)
            {
                if (!_isStarted)
                {
                    startupGameServer();
                }
                else
                {
                    shutdownGameServer();
                }
            }
        });
        setLayout(new BorderLayout(0, 0));

        _jTextArea = new JTextArea();
        add(_jTextArea);
        add(_jButtonStartGameServer, BorderLayout.NORTH);

        _initialized = true;
    }

    public void init()
    {
        System.out.println("init... " + Thread.currentThread());
        try
        {
            SwingUtilities.invokeAndWait(new Runnable()
            {
                public void run()
                {
                    initComponents();
                }
            });
        }
        catch (InvocationTargetException e)
        {
            e.printStackTrace();
        }
        catch (InterruptedException e)
        {
            e.printStackTrace();
            Thread.currentThread().interrupt();
        }
    }

    public void start()
    {
        System.out.println("start... " + Thread.currentThread());
        SwingUtilities.invokeLater(new Runnable()
        {
            public void run()
            {
                setSize(640/2, 480/2);
            }
        });
    }

    public void stop()
    {
        System.out.println("stop... " + Thread.currentThread());
        shutdownGameServer();
    }

    public void destroy()
    {
        System.out.println("destroy " + Thread.currentThread());
        shutdownGameServer();
    }

    void displayException(Throwable t)
    {
        log("Got exception: " + t);
    }


    void processMessageFromOtherPlayer(String msg)
    {
        log("Received message from other player: " + msg);
    }

    void gameServerThreadExiting()
    {
        shutdownGameServer();
    }

    public void startupGameServer()
    {
        _gameServer = new GameServer();
        _gameServerThread = new Thread(_gameServer);
        _gameServerThread.start();
        _isStarted = true;
        _jButtonStartGameServer.setText("Stop Game Server");
    }

    public void shutdownGameServer()
    {
        GameServer gs = _gameServer;
        if (gs != null)
        {
            gs.cancel();
        }
        Thread t = _gameServerThread;
        try
        {
            if (t != null)
            {
                t.join();
            }
        }
        catch (InterruptedException ie)
        {
            Thread.currentThread().interrupt();
        }
        _gameServer = null;
        _jButtonStartGameServer.setText("Start Game Server");
        _isStarted = false;
    }

    void log(final String msg)
    {
        System.out.println("Log (" + Thread.currentThread() + "): " + msg);
        Runnable r = new Runnable()
        {
            public void run()
            {
                StringBuilder sb = new StringBuilder(_jTextArea.getText());
                sb.append(msg);
                sb.append("\n");
                _jTextArea.setText(sb.toString());
            }
        };
        if (SwingUtilities.isEventDispatchThread())
        {
            r.run();
        }
        else
        {
            SwingUtilities.invokeLater(r);
        }
    }

    class GameServer implements Runnable
    {
        volatile ServerSocket _ss = null;
        volatile Socket _s = null;
        volatile InputStream _sis = null;
        volatile boolean _cancel = false;

        public void run()
        {
            try
            {
                _ss = new ServerSocket(9999);
                log("Waiting for other player, listening on port: " + _ss.getLocalPort());
                _s = _ss.accept();
                log("Connection accepted from: " + _s.getRemoteSocketAddress());
                _sis = _s.getInputStream();
                BufferedReader br = new BufferedReader(new InputStreamReader(_sis, "UTF-8"));
                while (true)
                {
                    if (_cancel)
                    {
                        break;
                    }
                    final String msg = br.readLine();
                    if (msg == null)
                    {
                        // connection closed / lost
                        break;
                    }
                    SwingUtilities.invokeLater(new Runnable()
                    {
                        public void run()
                        {
                            processMessageFromOtherPlayer(msg);
                        }
                    });
                }
            }
            catch (final Throwable t)
            {
                // don't show the user the exception if the user is canceling
                if (!_cancel)
                {
                    SwingUtilities.invokeLater(new Runnable()
                    {
                        public void run()
                        {
                            displayException(t);
                        }
                    });
                }
                else
                {
                    // even if the user is canceling, we might be interested in the exception, though
                    t.printStackTrace();
                }
            }
            log("Game server thread exiting...");
            SwingUtilities.invokeLater(new Runnable()
            {
                public void run()
                {
                    gameServerThreadExiting();
                }

            });
        }

        public void cancel()
        {
            _cancel = true;

            ServerSocket ss = _ss;
            if (ss != null)
            {
                try
                {
                    ss.close();
                }
                catch (IOException e)
                {
                    e.printStackTrace();
                }
            }

            Socket s = _s;
            if (s != null)
            {
                try
                {
                    s.close();
                }
                catch (IOException e)
                {
                    e.printStackTrace();
                }
            }

            InputStream sis = _sis;
            if (sis != null)
            {
                try
                {
                    sis.close();
                }
                catch (IOException e)
                {
                    e.printStackTrace();
                }
            }
        }
    }
}

你是如何处理线程的?在这种情况下,您可能需要使用。
clientSocket=serverSocket.accept()
正在导致您的
JFrame
冻结,因为它正在阻止
事件调度程序线程
。此部件应位于另一个
线程
SwingWorker
上,如前所述:-)您不应“在单独的线程上运行帧”。所有框架和GUI代码都应该在一个线程上运行:AWT调度线程。您应该将所有其他长时间运行的代码(例如等待接受套接字连接)移动到工作线程。SwingWorker可以让这更容易。但我希望在建立连接时冻结我的其他窗口。唯一要做出反应的窗口是在th=new Thread(){@Override public void run(){c=new Canceler(message);}中新打开的窗口;th.start()@125_m_125您永远不应该故意冻结GUI,因为在用户看来,它就像您的应用程序已崩溃或挂起(错误),并且在应用程序冻结时,您将无法响应用户输入(例如鼠标单击)。如果要防止用户在发生某些事情(例如,等待连接)时与GUI交互,请使用setEnabled(false)禁用GUI中的所有按钮,并忽略GUI事件(如windowClosing),直到后台活动完成。您的代码应能解决冻结问题,但另一个问题是,我仍然必须等待服务器连接,直到我可以继续进行其他计算。我该怎么做?另一件事是我必须返回一个值。服务器连接在代码
log(“连接接受自:”+_.getRemoteSocketAddress())行之后,因此您可以在那里放置更多代码。我不知道你具体的意思是什么:返回一个值。这有点模棱两可。我希望程序继续它以前的位置。比如:。。。if(mode==SERVER){info=//启动服务器并发送info2/receive info,否则if(mode==CLIENT){info2=//连接到服务器并发送info/receive info2}infototal=info+info2…”我不知道你具体说的是什么意思:返回一个值。这有点模棱两可服务器端和客户端都发送和接收一些数据,这些数据对于下面的计算是必需的,因此我必须返回这些信息。