以下に定義された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
。
Thread.sleep(0)
問題は、内のコードを削除するとrun()
、 がrun()
明らかに機能しなくなったことです。lstOfPendingStr
新しい要素で正常に更新されたにもかかわらず、ループ内のコードwhile(!lstOfPendingStr.isEmpty())
が呼び出されることはありませんでした。
System.out.println
またはThread.sleep(0)
(提供されたコードのように)などのハードコードを 内に配置するwhile(!stopLoop)
と、正常に機能しました。
スレッドを強制的に数ミリ秒間スリープさせることで問題を解決できましたが、この問題の背後にある理由を知りたいです。
あなたの知恵に感謝します。
由来 :)