2016-02-17 1 views
2

Все внутри GUIActions класс, который дал поле:Thread к глобальному переменным и силе убить старую нить

public class GUIActions { 
private GUIActions GUI; 
private JButton connectButton; 
private JTextArea messageArea; 

private String IP; 
private Integer PORT; 
private CommunicationManager comManager; 

public static Boolean flag = false; 

У меня есть код, который работает с управляющей связью: Он инициирует comManager и меняет флаг правда так ThreadManager будет знать, что он должен начать новый ReceiverThread

class connectButtonActionListener implements ActionListener { 

    @Override 
    public void actionPerformed(ActionEvent arg0) { 
     try { 
      comManager = null; //to make sure that old connection is erased 
      comManager = new CommunicationManager(IP, PORT); 
      flag = true; 
      if(!comManager.isAlive()) { 
       JOptionPane.showMessageDialog(null, "Can't connect with server \n Server is either unreachable or offline"); 
      } 
     } catch (IOException e) { 
      JOptionPane.showMessageDialog(null, "Can't connect with server \n Server is either unreachable or offline"); 
     } 
    } 
} 

код темы:

/* 
* @desc Static method that setup GUI including adding tabbed cards into Frame 
* @param -none- 
* @return -none- 
*/ 
public void setupGUI() { 
    JFrame frame = new JFrame("Chat Client"); 
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

    GUI = new GUIActions(); 
    GUI.setupCards(frame.getContentPane()); 

    Thread threadManager = new Thread(new ThreadManager()); 
    threadManager.start(); 

    frame.pack(); 
    frame.setVisible(true); 
} 

class ThreadManager implements Runnable { 
    public void run() { 
     while(true) { 
      try { 
       Thread.sleep(1000); 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 
      System.out.println("Looking for connection!"); 
      if(flag == true) { 
       System.out.println("Connection found!"); 
       Thread receiverThread = new Thread(new MessageReceiverRunnable()); 
       receiverThread.start(); 
       flag = false; 
      } 
     } 
    } 
} 

class MessageReceiverRunnable implements Runnable { 
    public synchronized void run() { 
     System.out.println("Thread running"); 
     BufferedReader reader; 
     String message; 
     try { 
      if(GUI.comManager==null) { 
       System.out.println("comManager null"); 
       if(GUI.IP == null || GUI.PORT == null) { 
        System.out.println("IP or PORT null"); 
       } 
       comManager = new CommunicationManager(GUI.IP, GUI.PORT); 
       reader = comManager.getReader(); 
      } else { 
       System.out.println("comManager NOT null"); 
       reader = GUI.comManager.getReader(); 
      } 
      while((message = reader.readLine()) != null) { 
       GUI.messageArea.append(message + "\n"); 
      } 
     } catch(Exception ex) { 
      ex.printStackTrace(); 
     } 
    } 
} 

Так ThreadManager ожидает подключения (comManager), и если есть соединение, он запускает новую тему, которая будет ждать входящих сообщений. У меня есть два вопроса:

1) Почему у меня есть доступ к полям GUIActions с GUI.IP или GUI.comManager вместо IP или comManager?

Класс Runnable thread находится внутри класса GUIActions! Связано ли это с тем, что каждый поток имеет отдельный стек?

2) Как я могу заставить убить старый приемникThread, когда есть новый инициализированный?

Cheers!

ответ

0
  1. У вас нет доступа к переменным класса-члена без использования объекта, который их связывает. Его правило на большинстве языков, поскольку они не являются глобальными константами, JVM (в данном случае) не знает, к каким переменным вы обращаетесь.

Не могли бы вы пояснить вопрос: «Класс Runnable thread внутри класса GUIActions! Связано ли это с тем, что каждый поток имеет отдельный стек?» ?

  1. Чтобы убить старый поток получателя, сохраните объект MessageReceiverRunnable в переменной и добавьте флаг, который приведет к выходу из метода run(). Когда создается новый поток приемника, измените флаг, чтобы поток завершился. Другой вариант - вызвать метод прерывания() в потоке.
+0

Это так: общественный класс GUIActions {класс MessageReceiverRunnable реализует Runnable {// можно получить доступ только к GUI.IP и IP является недействительным}} –

+0

Поскольку вы обращаетесь к объекту GUIAction «GUI», который вы объявленные внутри класс. Чтобы получить доступ к реальным IP и comManager, вы должны использовать GUIAction.this.IP и GUIAction.this.comManager – Nadir

Смежные вопросы