如果输入的听众同步?(Should input listeners be synchronized?

2019-07-20 02:06发布

下面贴出我的代码示例显示了两个班。 一个实现的KeyListener和其他实现Runnable和无限循环睡觉,每隔20毫秒运行。 当一个键被按下作为keyChar,这是在一个int的形式,被用作索引设置一个布尔阵列真或假,表示与所述键被按下或不的索引。 同时,在处理循环搜索它的真或假值的键部分并设置真实的人假然后打印出来的字符。 我的问题是我是否不再需要使用用于访问charArray,因为它是在两个线程使用的锁使用同步:进程线程和关键监听线程。

示例代码:

import java.awt.Component;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

public class Input implements KeyListener {

public boolean[] charArray;

public Input(Component component) {
    charArray = new boolean[127];
    component.addKeyListener(this);
}

@Override
public void keyPressed(KeyEvent e) {
            (possible synchronization with a lock?)
    int keyChar = e.getKeyChar();
    if (keyChar == 27 || keyChar == 9 || keyChar == 10 || keyChar == 127) //useless keys like del, tab, esc, etc..
        keyChar = 65535;
    if (keyChar < 65535) //65535 represents no true char value
        charArray[keyChar] = true;
}

@Override
public void keyReleased(KeyEvent e) {
}

@Override
public void keyTyped(KeyEvent e) {
}
}




import java.awt.Dimension;
import javax.swing.JFrame;

@SuppressWarnings("serial")
public class Process extends JFrame implements Runnable {

private boolean running;
private Input input;

public Process() {
    running = false;
    input = new Input(this);
    setTitle("Keyboard Test");
    setSize(new Dimension(200, 200));
    toFront();
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setVisible(true);
}

/**
 * @param args
 */
public static void main(String[] args) {
    new Process().startThread();
}

public synchronized void startThread() {
    running = true;
    new Thread(this).start();
}

@Override
public void run() {
    while (running) {
                    (possible synchronization with a lock?)
        for (int i = 0; i < input.charArray.length; i++) {
            if (input.charArray[i] == true) {
                input.charArray[i] = false;
                System.out.println((char) i);
            }
        }
        try {
            Thread.sleep(20);
        } catch (InterruptedException e) {
        }
    }
}
}

Answer 1:

charArray变量是从至少两个线程(你在进程启动一个与EDT在你输入类)的访问,所以你需要将这些同步访问,以确保能见度(即确保一个线程所做的更改是可见的与其他线)。

请注意,在你的代码中的其他一些问题,例如:

  • 你不应该让这种逃避施工过程中(通过调用input = new Input(this)component.addKeyListener(this) ) -这会导致怪异的行为在多线程环境
  • 你应该尝试有一个JFrame的内部变量Process类,而不是延伸JFrame
  • 我不知道您打算如何设置running为false,但在你周围的变量没有同步run方法,所以你可能不会看到它变成假的。


Answer 2:

当涉及到AWT或Swing的头号规则是永远不要synchonize或以其他方式分派线程干扰。 如果你不熟悉这个再看看在分派线程问题

在你的情况我将完全分开的非GUI线程功能集成到一个单独的类 - 并使用java.util.concurrent中真正有用的一个类,如果有必要在两者之间进行通信。

如果你得到一个锁或延迟由于线程问题,你在分派线程实际上是整个图形用户界面将冻结



文章来源: Should input listeners be synchronized?