为什么在以下示例中未更新ArrayList?

时间:2015-08-16 17:22:08

标签: java

我正在使用JNativeHook库。

GlobalKeyListener的实例开始收听击键并将其添加到arrayList1;问题是arrayList1似乎没有得到更新(list1itemCount永远不会变大,然后0)通过Child类中的无限while(true)循环访问它。为什么这样做,我该怎么做才能实现这一目标?

public class Child {
    public static void main(String[] args) {
        // Get the logger for "org.jnativehook" and set the level to warning.
        Logger logger = Logger.getLogger(GlobalScreen.class.getPackage().getName());
        logger.setLevel(Level.WARNING);
        try {
            GlobalScreen.registerNativeHook();
        }
        catch (NativeHookException ex) {
            System.err.println("There was a problem registering the native hook.");
            System.err.println(ex.getMessage());

            System.exit(1);
        }

        GlobalKeyListener globalkeylistener = new GlobalKeyListener();
        GlobalScreen.addNativeKeyListener(globalkeylistener);
        Connection conn;
        while(true){
            int list1itemCount = globalkeylistener.arrayList1.size();
            if (list1itemCount >= 4)
                System.out.println(list1itemCount);
        }
    }
}

GlobalKeyListener类:

public class GlobalKeyListener implements NativeKeyListener {
    ArrayList<Class1> arrayList1 = new ArrayList<>();
    public ArrayList<Class1> listing() {
        return arrayList1;
    }

    public void nativeKeyPressed(NativeKeyEvent e) {
        arrayList1.add(new Class1(e.getKeyCode(), 1));
    }

    public void nativeKeyReleased(NativeKeyEvent e) {
        arrayList1.add(new Class1(e.getKeyCode(), 0));
    }

    public void nativeKeyTyped(NativeKeyEvent e) {
    }
}

1 个答案:

答案 0 :(得分:1)

这是一个多线程问题。 keyEvent更新发生在其他线程上,您的while(true)将不会更新。此外,ArrayList本身并不像您编写的那样是线程安全的。

最好同步一些东西(最容易的,不一定是最好的)是关键监听器本身,让它等到更新发生然后通知。这是修改后的代码:

GlobalKeyListener.java

public class GlobalKeyListener implements NativeKeyListener {
  ArrayList<Class1> arrayList1 = new ArrayList<>();
  public ArrayList<Class1> listing() {
      return arrayList1;
  }

  public void nativeKeyPressed(NativeKeyEvent e) {
    synchronized(this) {
      arrayList1.add(new Class1(e.getKeyCode(), 1));
      this.notifyAll();
    }
  }

  public void nativeKeyReleased(NativeKeyEvent e) {
    synchronized(this) {
      arrayList1.add(new Class1(e.getKeyCode(), 0));
      this.notifyAll();
    }
  }

  public void nativeKeyTyped(NativeKeyEvent e) {
  }
}

Child.java

public class Child {
  public static void main(String[] args) throws InterruptedException {
    Logger logger = Logger.getLogger(GlobalScreen.class.getPackage().getName());
    logger.setLevel(Level.WARNING);
      try {
          GlobalScreen.registerNativeHook();
      }
      catch (NativeHookException ex) {
          System.err.println("There was a problem registering the native hook.");
          System.err.println(ex.getMessage());

          System.exit(1);
      }

      GlobalKeyListener globalkeylistener = new GlobalKeyListener();
      GlobalScreen.addNativeKeyListener(globalkeylistener);
      synchronized(globalkeylistener) {
        while(true){
            int list1itemCount = globalkeylistener.arrayList1.size();
            if (list1itemCount >= 4) {
                System.out.println(list1itemCount);
            }
            globalkeylistener.wait();
        }
      }
  }
}