2015-04-05 34 views
0

我正在实施聊天程序。每当用户点击Player.java中的“START”时,它将终止前一个Chatter线程并构建一个新的线程来启动。 Chatter线程具有用于聊天的GUI。无法中断线程

我通过interrupt()方法终止Chatter线程。我认为它会在Chatter线程中设置标志,以便通过检查isInterrupted()来终止它,但它总是为false。但它应该当我Player.java

这里调用中断()是真的是我的代码: Player.java

public class Player implements GameConstants{ 
     /** 
     * This listener is used when the user clicks QUIT in the GUI. 
     */ 
     private class ControlListener implements ActionListener{ 

      /** 
      * This method sends QUIT to the server when the listener is triggered. 
      * @param e ActionEvent 
      */ 
      @Override 
      public void actionPerformed(ActionEvent e){  
       String cmd = ((JButton)(e.getSource())).getText(); 

       if ("START".equals(cmd)) { 

        //I interrupt the thread using this 
        if (chatThread !=null) { 
         System.err.println("before interruped"); 
         chatThread.interrupt(); 
        } 

        chatThread = new Chatter(ip,senderName); 
        chatThread.start(); 
       } 


      } 
     } 
    } 

下面是Chatter.java

public class Chatter extends Thread implements GameConstants{ 
     private JTextArea log; 
     private String senderName; 
     private DataInputStream fromServer; 
     private DataOutputStream toServer; 
     private JTextField inputField; 
     private SoundPlayer msgSound; 
     private Socket socket; 



     private class SendListener implements ActionListener{ 
      @Override 
      public void actionPerformed(ActionEvent e){ 
       String msg = inputField.getText(); 
       inputField.setText(""); 
       try { 
        toServer.writeUTF(""+(new Date())+ "\n" + senderName + ": "+msg); 
        toServer.flush(); 
       } catch(IOException ex) { 
        System.err.println(ex.getMessage()); 
       } 
      } 

     } 


     public Chatter(String ip, String senderName){ 
      this.senderName = senderName; 

      buildGUI(); 
      try{ 
       socket = new Socket(ip,CHAT_PORT); 
       fromServer = new DataInputStream(socket.getInputStream()); 
       toServer = new DataOutputStream(socket.getOutputStream()); 
      }catch(IOException e){ 
       System.out.println(e.getMessage()); 
      } 
     } 

     @Override 
     public void run(){ 
      try { 
       while(!isInterrupted()){ 
        String msg = fromServer.readUTF(); 
        report(msg); 
       } 

      } catch(IOException e) { 
       System.err.println(e.getMessage()); 
      }finally{ 
       try { 
        socket.close(); 
       } catch(Exception e) { 
       } 

      }   

     } 


     private void buildGUI(){ 
      JFrame frame = new JFrame(); 
      frame.setSize(WIDTH,HEIGHT); 
      frame.setTitle("Chat Room - " + senderName); 
      frame.setResizable(false); 
      // .... just building the GUI 

      frame.add(parentPanel); 
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
      frame.setVisible(true); 
     } 

    } 
+0

'msgSound.play()'做了什么?请考虑花时间将您的代码缩减为[最小完整示例](http://stackoverflow.com/help/mcve)。否则,我们花时间猜测。 – Radiodef 2015-04-05 18:12:19

+0

感谢您的反馈。我刚刚删除它。 – Fan 2015-04-05 18:15:31

+0

好的,删除它并没有什么帮助。我得到的一点是你没有发布所有相关的代码。有些操作可以清除中断标志,或者您正在捕获'InterruptedException'。目前这个问题是无法回答的,因为代码不会重现问题。例如见[Ideone示例](http://ideone.com/ZoY6ph),它显示'interrupt' /'isInterrupted'单独正确工作。 – Radiodef 2015-04-05 18:22:35

回答

0

当你中断一个线程,它可能会抛出InterruptedException,如果它正在等待一些IO操作或类似的。其中断标志将在抛出异常后被清除,并且将再次为假。

+1

它不会抛出InterruptedException,因为线程未处于睡眠状态。我之所以使用中断()来检查是因为线程没有处于睡眠状态。因此,我无法捕捉到不会抛出的InterruptedException。 – Fan 2015-04-05 18:18:46

+0

@Fan'Thread.sleep'不是抛出'InterruptedException'的唯一方法。如果你有例如'catch(Exception e)'这样的东西,你可能会错误地捕捉它。 – Radiodef 2015-04-05 18:26:11

+1

您已经在阻止方法的循环中调用方法readUTf。所以它会抛出你已经捕获到的InterruptedException,但是对于终止T​​hread没有任何作用。你可以在那里终止Thread。 – jimmy0251 2015-04-05 18:26:57