[英]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.println
或Thread.sleep(0)
类的硬代码(如提供的代码)放入while(!stopLoop)
,然后工作正常。
尽管我通过强制线程休眠数毫秒来解决了该问题,但我想知道此问题的原因。
感谢您的智慧。
问候:)
你有几个问题。
lstOfPendingStr
方法,但使用LinkedList
对其进行了初始化,该方法不是线程安全的。 您应该使用线程安全类,据我从您的代码了解, LinkedBlockingQueue
似乎是最好的选择。 JTextArea#append()
。 与所有AWT / Swing方法一样,您不能从任意线程调用它们,而只能从AWT线程调用它们。 将调用包装在invokeLater
块内。 sleep
似乎可以使您的代码正常工作,这仅仅是并发问题的迹象。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.