Java 即使在其他线程中启动,帧也会冻结
我希望在我的程序与其他播放器连接时显示一个帧。但是,即使框架在他自己的线程中运行,当Serversocket尝试连接时,它仍然处于冻结状态。我怎样才能防止它结冰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
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…”我不知道你具体说的是什么意思:返回一个值。这有点模棱两可服务器端和客户端都发送和接收一些数据,这些数据对于下面的计算是必需的,因此我必须返回这些信息。