线程访问全局变量并强制终止旧线程

时间:2016-02-17 12:06:10

标签: java multithreading

所有内容都在GUIActions类中,该类提供了字段:

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并将标志更改为true,以便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)为什么我必须使用GUI.IP或GUI.comManager而不是IP或comManager访问GUIActions字段?

Runnable线程类在GUIActions类中!是否与每个线程都有单独的堆栈连接?

2)当新的初始化时,如何强行杀掉旧的receiverThread?

干杯!

1 个答案:

答案 0 :(得分:1)

  1. 如果不使用包含它们的对象,则无法访问类成员变量。它是大多数语言中的规则,因为它们不是全局常量,JVM(在这种情况下)并不知道您所引用的变量。
  2. 你能否澄清问题" Runnable线程类在GUIActions类中!是否与每个线程都有单独的堆栈连接?" ?

    1. 要终止旧接收器线程,请将MessageReceiverRunnable对象存储在变量中,并添加一个将退出run()方法的标志。创建新的接收器线程时,修改该标志以便线程完成。另一种选择是在线程上调用interrupt()方法。