输入侦听器是否应该同步? [英] Should input listeners be synchronized?

查看:79
本文介绍了输入侦听器是否应该同步?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

下面发布的我的示例代码显示了两个类.一个实现KeyListener,另一个实现Runnable,并在无限循环中运行,每20毫秒休眠一次.当按下某个键时,采用int形式的keyChar用作索引,它设置布尔数组的索引true或false,表示是否按下了该键.同时,过程循环在键数组中搜索其true或false值,并将true设置为false,然后打印出char.我的问题是我是否需要使用带锁的同步来访问charArray,因为它在两个线程中使用:进程线程和键侦听器线程.

My sample code posted below shows two classes. One implements KeyListener and the other implements Runnable and is running in an infinite loop sleeping every 20 ms. When a key is pressed the keyChar, which is in the form of an int, is used as an index setting the index of a boolean array true or false, representing with the key was pressed or not. At the same time the process loop is searching the key array for its true or false values and setting the true ones false then printing out the char. My question is whether or not I need to use synchronization using a lock for accessing the charArray because it is used in two threads: the process thread and the key listener thread.

示例代码:

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) {
        }
    }
}
}

推荐答案

至少从两个线程(您在Process中启动的一个线程和您的Input类中的EDT)访问您的charArray变量,因此您需要同步这些线程访问以确保可见性(即,确保一个线程的更改对另一线程可见).

Your charArray variable is accessed from at least two threads (the one you start in Process and the EDT in your Input class) so you need to synchronize those accesses to ensure visibility (i.e. make sure that changes made by one thread are visible from the other thread).

请注意,您的代码中还有其他几个问题,例如:

Note that there are several other issues in your code, for example:

  • 您不应在构造期间通过调用input = new Input(this)component.addKeyListener(this)使其逃逸-这可能导致在多线程环境中出现怪异的行为
  • 您应该尝试在Process类中包含一个JFrame变量,而不是扩展JFrame
  • 我不确定您打算如何将running设置为false,但是在run方法中该变量周围没有同步,因此您可能看不到它变为false.
  • you should not let this escape during construction (by calling input = new Input(this) or component.addKeyListener(this)) - this can lead to weird behaviour in a multi-threaded environment
  • you should try to have a JFrame variable inside your Process class instead of extending JFrame
  • I'm not sure how you plan to set running to false, but there is no synchronization around that variable in your run method so you might not see it become false.

这篇关于输入侦听器是否应该同步?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆