事件调度线程同步

沃尔夫冈·法尔

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

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

  1. 要创建的GUI / JFrame
  2. 文本字段的修改

首先,我尝试了对相应的布尔锁定对象的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();
    }
  }
}
沃尔夫冈·法尔

如果使用“锁定”类,则该方法有效。最初,我使用了布尔型,但由于这些锁定对象被赋值替换了,所以它不起作用,例如

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

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

线程与事件同步

来自分类Dev

覆盖AWT事件调度线程

来自分类Dev

将逻辑线程与事件调度线程分开

来自分类Dev

Swing并发和事件调度线程

来自分类Dev

JRuby和Swing事件调度线程

来自分类Dev

scala,swing:事件调度线程(actor)发生线程问题

来自分类Dev

JavaFX事件调度线程与JavaFX应用程序线程?

来自分类Dev

与angular同步事件(例如线程'join()'函数)

来自分类Dev

如何返回等待调度程序线程中的事件的等待(任务?)

来自分类Dev

java awt事件队列/调度线程未知源错误?

来自分类Dev

如何实现将结果返回给事件调度线程的方法?

来自分类Dev

由于隐式线程,C#无法调度事件

来自分类Dev

CUDA线程调度:自定义线程交换/基于事件的锁?

来自分类Dev

线程同步?

来自分类Dev

线程同步

来自分类Dev

线程同步?

来自分类Dev

多线程,线程同步

来自分类Dev

为什么应该仅在事件调度线程上访问Swing组件?

来自分类Dev

将事件调度线程置于保持状态,直到Swing计时器停止

来自分类Dev

实现实时的1毫秒准确事件,而无需进行线程调度

来自分类Dev

将事件调度线程置于保持状态,直到Swing计时器停止

来自分类Dev

线程和任务调度

来自分类Dev

了解线程调度模式

来自分类Dev

JScrollPane不调度事件

来自分类Dev

调度事件发生多次

来自分类Dev

调度事件与数据

来自分类Dev

chrome事件未调度

来自分类Dev

协调视图/调度事件

来自分类Dev

事件的调度算法