繁体   English   中英

run()的Java线程问题

[英]Java Threading Issue with run()

我在下面定义了2个类:

public class TextsManager extends Thread {
    LinkedList<String> lstOfPendingStr = new LinkedList<String>();

    boolean stopLoop = false;

    JTextArea txtArea;
    public void run()
    {
        while (!stopLoop)
        {               
            while (!lstOfPendingStr.isEmpty())
            {               
                String tmp = lstOfPendingStr.getFirst();
                this.txtArea.append(tmp);                   
                lstOfPendingStr.removeFirst();              
            }

            try {
                Thread.sleep(0);    //  note: I had to force this code
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }           
        }       
    }

    public void AddNewStr(String newStr)
    {       
        this.lstOfPendingStr.add(newStr);   
    }   

}

public class ClientApp {

    private JFrame frame;
    private JTextField textField;
    private JTextArea textArea;
    static private TextsManager txtManager;
    /**
     * Launch the application.
     */
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    ClientApp window = new ClientApp();
                    window.frame.setVisible(true);                  
                } catch (Exception e) {
                    e.printStackTrace();
                }               
            }
        });     
    }

    /**
     * Create the application.
     */
    public ClientApp() {
        initialize();

        /*
         * Client app
         */
        txtManager =  new TextsManager(textArea);

        txtManager.start();     
    }

    /**
     * Initialize the contents of the frame.
     */
    private void initialize() {
        frame = new JFrame();

        textArea = new JTextArea(); 

        textField = new JTextField();
        textField.addKeyListener(new KeyAdapter() {
            @Override
            public void keyPressed(KeyEvent e) {
                if (e.getKeyCode() == KeyEvent.VK_ENTER)
                {
                    txtManager.AddNewStr(textField.getText() + "\n");
                    textField.setText("");
                }
            }
        });

    }

}

该程序将从textField读取用户输入,并将其传递到TextsManager.lstOfPendingStr 然后,在TextsManager.run ()内部的每个循环上,它将检查lstOfPendingStr是否存在成员,并通过txtArea输出它们。

问题是,如果我删除了run()的代码Thread.sleep(0) run() ,则run()显然停止了工作。 尽管已成功用新元素更新了lstOfPendingStr ,但循环中的while(!lstOfPendingStr.isEmpty())将永远不会被调用。

我将诸如System.out.printlnThread.sleep(0)类的硬代码(如提供的代码)放入while(!stopLoop) ,然后工作正常。

尽管我通过强制线程休眠数毫秒来解决了该问题,但我想知道此问题的原因。

感谢您的智慧。

问候:)

你有几个问题。

  1. 您正在从两个线程调用lstOfPendingStr方法,但使用LinkedList对其进行了初始化,该方法不是线程安全的。 您应该使用线程安全类,据我从您的代码了解, LinkedBlockingQueue似乎是最好的选择。
  2. 在线程内,您正在调用JTextArea#append() 与所有AWT / Swing方法一样,您不能从任意线程调用它们,而只能从AWT线程调用它们。 将调用包装在invokeLater块内。

sleep似乎可以使您的代码正常工作,这仅仅是并发问题的迹象。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM