2016-07-14 44 views
1

为了更好地理解美国东部时间同步沿事件指派线程同步

是如何工作的我已经创建了一个简单的测试用例JUnit3 - 见下文。我们的目标是要等待两个事件:

  1. /要创建的JFrame
  2. 一个文本框

首先修改我试过一个wait()上相应的布尔锁定对象调用GUI但没有按预期那样工作。然后我试着循环等待布尔锁定内容。这两种方法都不像我预期的那样工作。

如何修改下面的代码以获得预期的等待行为?如果使用 “锁定” 类

JUnit的测试用例

package com.bitplan.test.common; 

import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.JTextField; 
import javax.swing.SwingUtilities; 
import javax.swing.event.DocumentEvent; 
import javax.swing.event.DocumentListener; 

import junit.framework.TestCase; 

/** 
* test the event dispatching thread handling 
* 
* @author wf 
* 
*/ 
public class TestEDT extends TestCase { 


    private JTextField field; 
    private Boolean modified=new Boolean(false); 
    private Boolean created=new Boolean(false); 

    /** 
    * test UI handling 
    * 
    * @throws InterruptedException 
    */ 
    public void testUI() throws InterruptedException { 
    // see 
    // http://docs.oracle.com/javase/tutorial/uiswing/concurrency/initial.html 
    SwingUtilities.invokeLater(new Runnable() { 
     public void run() { 
     createAndShowGUI(); 
     } 
    }); 
    synchronized(created) { 
     created.wait(); 
     /** 
     while(!created.isTrue()) { 
     Thread.sleep(10); 
     } */ 
    } 
    field.getDocument().addDocumentListener(new DocumentListener() { 
     public void flagModification() { 
     synchronized(modified) { 
      modified=true; 
      modified.notify(); 
     }  
     } 
     public void insertUpdate(DocumentEvent e) { 
     flagModification(); 
     } 

     @Override 
     public void removeUpdate(DocumentEvent e) {  
     flagModification(); 
     } 

     @Override 
     public void changedUpdate(DocumentEvent e) { 
     flagModification();   
     } 
    }); 
    SwingUtilities.invokeLater(new Runnable() { 
     public void run() { 
     updateField("fieldcontent"); 
     } 
    }); 
    synchronized(modified) { 
     // https://stackoverflow.com/questions/2536692/a-simple-scenario-using-wait-and-notify-in-java?noredirect=1&lq=1 
     modified.wait(); 
     /** 
     while(!modified) { 
     Thread.sleep(10); 
     } */ 
    } 
    } 

    /** 
    * update the field with the new content; 
    * 
    * @param newContent 
    */ 
    protected void updateField(String newContent) { 
    field.setText(newContent); 
    } 

    /** 
    * create and show the given gui 
    */ 
    protected void createAndShowGUI() { 
    JFrame frame = new JFrame(); 
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    frame.setTitle("Example GUI"); 
    JPanel panel = new JPanel(); 
    field = new JTextField(30); 
    panel.add(field); 
    frame.setContentPane(panel); 
    frame.pack(); 
    frame.setVisible(true); 
    synchronized(created) { 
     created=true; 
     created.notify(); 
    } 
    } 
} 
+0

你知道你会注册Listeners做什么的要求是吧? https://docs.oracle.com/javase/tutorial/uiswing/events/ – Fildor

+0

另请参阅:[如何使用文本字段](https://docs.oracle.com/javase/tutorial/uiswing/components/textfield.html ) – Fildor

+0

而且 - 你期望的行为是什么?你想做什么?你没有等待锁定。请注意,created.wait()被notify()中断,Thread.sleep()需要被相应线程上的interrupt()中断。并等待10ms似乎也不可见。 – gusto2

回答

1

的方法效果。最初我使用过布尔值,因为这些锁定对象被赋值取代,所以不起作用。所以created.notify()信号不同的对象,并不会停止在主线程等待

created=true. 

将创建一个新的独立的Boolean对象。

The Lock version works。我已将我的问题代码更改回原始错误的布尔版本以显示该点。

package com.bitplan.test.common; 

import java.awt.Frame; 

import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.JTextField; 
import javax.swing.SwingUtilities; 
import javax.swing.event.DocumentEvent; 
import javax.swing.event.DocumentListener; 

import junit.framework.TestCase; 

/** 
* test the event dispatching thread handling 
* 
* @author wf 
* 
*/ 
public class TestEDT extends TestCase { 

    public static class Lock { 

    boolean value; 

    public Lock(boolean value) { 
     super(); 
     this.value = value; 
    } 
    /** 
    * @return the value 
    */ 
    public boolean isTrue() { 
     return value; 
    } 

    /** 
    * @param value the value to set 
    */ 
    public void set(boolean value) { 
     this.value = value; 
    } 
    } 
    private JTextField field; 
    private Lock modified=new Lock(false); 
    private Lock created=new Lock(false); 

    /** 
    * test UI handling 
    * 
    * @throws InterruptedException 
    */ 
    public void testUI() throws InterruptedException { 
    // see 
    // http://docs.oracle.com/javase/tutorial/uiswing/concurrency/initial.html 
    SwingUtilities.invokeLater(new Runnable() { 
     public void run() { 
     createAndShowGUI(); 
     } 
    }); 
    synchronized(created) { 
     while(!created.isTrue()) 
     created.wait(); 
    } 
    field.getDocument().addDocumentListener(new DocumentListener() { 
     public void flagModification() { 
     synchronized(modified) { 
      modified.set(true); 
      modified.notify(); 
     }  
     } 
     public void insertUpdate(DocumentEvent e) { 
     flagModification(); 
     } 

     @Override 
     public void removeUpdate(DocumentEvent e) {  
     flagModification(); 
     } 

     @Override 
     public void changedUpdate(DocumentEvent e) { 
     flagModification();   
     } 
    }); 
    SwingUtilities.invokeLater(new Runnable() { 
     public void run() { 
     updateField("fieldcontent"); 
     } 
    }); 
    synchronized(modified) { 
     while(!modified.isTrue()) 
     // http://stackoverflow.com/questions/2536692/a-simple-scenario-using-wait-and-notify-in-java?noredirect=1&lq=1 
     modified.wait(); 
    } 
    } 

    /** 
    * update the field with the new content; 
    * 
    * @param newContent 
    */ 
    protected void updateField(String newContent) { 
    field.setText(newContent); 
    } 

    /** 
    * create and show the given gui 
    */ 
    protected void createAndShowGUI() { 
    JFrame frame = new JFrame(); 
    frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 
    frame.setTitle("Example GUI"); 
    JPanel panel = new JPanel(); 
    field = new JTextField(30); 
    panel.add(field); 
    frame.setContentPane(panel); 
    frame.pack(); 
    frame.setVisible(true); 
    synchronized(created) { 
     created.set(true); 
     created.notify(); 
    } 
    } 
}