Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 事件调度线程同步_Java_Multithreading_Swing_Junit - Fatal编程技术网

Java 事件调度线程同步

Java 事件调度线程同步,java,multithreading,swing,junit,Java,Multithreading,Swing,Junit,为了更好地了解EDT同步是如何工作的 及 我已经创建了一个简单的JUnit3测试用例——见下文。目标是等待两个事件: 要创建的GUI/JFrame 文本字段的修改 首先,我对相应的布尔锁对象尝试了wait()调用,但没有按预期工作。然后我尝试了一个循环,等待布尔锁内容。这两种方法都不像我预期的那样有效 如何修改下面的代码以获得预期的等待行为? JUnit测试用例 package com.bitplan.test.common; import javax.swing.JFrame; i

为了更好地了解EDT同步是如何工作的

我已经创建了一个简单的JUnit3测试用例——见下文。目标是等待两个事件:

  • 要创建的GUI/JFrame
  • 文本字段的修改
  • 首先,我对相应的布尔锁对象尝试了wait()调用,但没有按预期工作。然后我尝试了一个循环,等待布尔锁内容。这两种方法都不像我预期的那样有效

    如何修改下面的代码以获得预期的等待行为?

    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();
        }
      }
    }
    
    如果使用了“Lock”类,则该方法有效。最初我使用的是布尔值,但这不起作用,因为这些锁对象被赋值替换,例如

    created=true. 
    
    将创建一个新的单独布尔对象,因此created.notify()会向另一个对象发送信号,并且不会停止主线程中的等待

    锁定版本可以工作。我已经将我的问题代码改回了原来错误的布尔版本,以说明这一点

    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();
        }
      }
    }
    

    您知道您会注册侦听器来执行要求,对吗?另请参见:您期望的行为是什么?你想干什么?您没有等待锁。注意,created.wait()被notify()中断,Thread.sleep()需要被相应线程上的interrupt()中断。等待10毫秒似乎也不可见。我现在明白了-你在创建的锁上创建了一个死锁。尝试使用create.wait()而不是sleep,并将SwingUtilities.invokeLater放在synchronized语句中(因此省略线程竞争)。最后,需要从AWS线程更新JTextFied。感谢您的评论。我使用Lock类是正确的,但是在引入了这个类之后,我没有尝试等待方法。最初我是和布尔人一起去的,但这并不像下面的答案所解释的那样有效。