【发布时间】:2011-12-04 03:01:36
【问题描述】:
假设您在网络游戏中有以下计时器的代码实现:
public void DefineTimer()
{
Action updateClockAction = new AbstractAction() {
public void actionPerformed(ActionEvent e){
//System.out.println(javax.swing.SwingUtilities.isEventDispatchThread());
JPanelMainGame.this.jLabelSeconds.setFont(new java.awt.Font("Lucida Handwriting", 1, 36));
JPanelMainGame.this.jLabelSeconds.setForeground(Color.red);
JPanelMainGame.this.jLabelSeconds.setText(Integer.toString(JPanelMainGame.this.m_TimerTotalSeconds));
if( JPanelMainGame.this.m_TimerTotalSeconds >0)
{
JPanelMainGame.this.m_TimerTotalSeconds--;
}
else if ( JPanelMainGame.this.m_TimerTotalSeconds == 0)
{
// System.out.println(javax.swing.SwingUtilities.isEventDispatchThread());
JPanelMainGame.this.m_Timer.stop();
JPanelMainGame.this.jLabelSeconds.setText("0");
JPanelMainGame.this.jButtonFinish.setVisible(false);
System.out.println("after JbuttonFinish set visble false");
System.out.println("!m_WasGameDecisived: "+!m_WasGameDecisived);
// System.out.println(javax.swing.SwingUtilities.isEventDispatchThread());
JPanelGameApplet gameApplet = (JPanelGameApplet) getTopLevelAncestor();
//Checking whether time ended for both players and no solution was recieved
if(gameApplet.GetJPanelChooseGame().GetGameType() == eGameType.Net)
{
gameApplet.GetClinetThread().UpdateServerOfTimeEnded();
System.out.println("After Update");
if (!m_WasGameDecisived)
{
// System.out.println(javax.swing.SwingUtilities.isEventDispatchThread());
System.out.println("Tie - No one had a solution in the given time");
gameApplet.GetClinetThread().SendRequestToClosePlayerThreadAndRemoveItFromPlayersOnServer();
System.out.println("After SendRequestToClosePlayerThread");
gameApplet.GetClinetThread().CloseSocket();
System.out.println("After CloseSocket");
Menu.BrowseTo(PanelMenuNumber.k_ChooseGame, JPanelMainGame.this.getParent());
//askUserForAnotherRoundLeaveTableOrExitProgram();//////////////////////////////////////////////To implement
}
}
else if(gameApplet.GetJPanelChooseGame().GetGameType() == eGameType.Single)
{
JPanelMainGame.this.showPopUpSelectionBar();
}
}
}
};
m_Timer = new Timer(1000, updateClockAction);
}
我已经添加了这些函数(写入相同的 DataOutputStream:
gameApplet.GetClinetThread().UpdateServerOfTimeEnded();
gameApplet.GetClinetThread().SendRequestToClosePlayerThreadAndRemoveItFromPlayersOnServer();
添加它们后,我得到不一致的异常:
有时我会在客户端出现异常,因为其中一个功能,或者两者兼有,或者根本没有任何异常。
请帮我解决问题
我不时遇到的异常示例:
java.net.SocketException: Software caused connection abort: socket write error
at java.net.SocketOutputStream.socketWrite0(Native Method)
at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:92)
at java.net.SocketOutputStream.write(SocketOutputStream.java:115)
at java.io.DataOutputStream.writeInt(DataOutputStream.java:181)
at GUI.ClientCommunicationThread.UpdateServerOfTimeEnded(ClientCommunicationThread.java:851)
at GUI.JPanelMainGame$2.actionPerformed(JPanelMainGame.java:313)
at javax.swing.Timer.fireActionPerformed(Timer.java:271)
at javax.swing.Timer$DoPostEvent.run(Timer.java:201)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:597)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)
java.net.SocketException: Software caused connection abort: socket write error
at java.net.SocketOutputStream.socketWrite0(Native Method)
at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:92)
at java.net.SocketOutputStream.write(SocketOutputStream.java:115)
at java.io.DataOutputStream.writeInt(DataOutputStream.java:180)
at GUI.ClientCommunicationThread.SendRequestToClosePlayerThreadAndRemoveItFromPlayersOnServer(ClientCommunicationThread.java:825)
at GUI.JPanelMainGame$2.actionPerformed(JPanelMainGame.java:327)
at javax.swing.Timer.fireActionPerformed(Timer.java:271)
at javax.swing.Timer$DoPostEvent.run(Timer.java:201)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:597)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)
【问题讨论】:
-
在 EDT 上进行网络调用不是一个好主意
-
您最好将您的网络调用重构为
Runnable并在您的actionPerformed方法中调用SwingUtilities.invokeLater(Runnable)。 -
mmm ,你能给个例子代码吗,我以为我不能按照第一条评论在EDT做网络
-
public void actionPerformed(ActionEvent e) { SwingUtilities.invokeLater(new Runnable() { public void run() { /*your current networking code*/ } }); } -
对不起,它被称为 SwingWorker(没有空格),不,它不是执行后台线程的唯一方法,因为任何普通的普通后台线程都可以工作,但它有一些优点,包括发布/处理为如上所述,它是一个未来,所以它可以返回一些东西。它也有很好的 PropertyChange 支持。你可以在这里找到更多信息:Concurrency in Swing
标签: java multithreading swing sockets timer