[英]java swing keylistener and threads
不,这不是关于线程安全和添加密钥侦听器的一般问题:)
在摆动中使用键侦听器打开和关闭布尔值时遇到一个奇怪的问题:按下和释放键时,打开和关闭布尔值。 在另一个线程中,我读取了布尔值,并希望对其进行处理。 但是以某种方式,尽管布尔值必须为true,但无法访问if块,因为我握住了键。 如果我在本节中添加断点,则确实可以访问该断点,或者如果我在if块中添加了sleep。 为什么会这样呢? 有人可以解释吗?
编辑:奇怪。 使用AtomicBoolean可解决此问题。 这可以是活锁吗?
package de.osipovan.rccontroller.gui;
import java.awt.BorderLayout;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
public class Test extends JFrame implements KeyListener {
private static final long serialVersionUID = -8395585938567486151L;
private JPanel contentPane;
private boolean doIt = false;
private Thread t = new Thread(new Runnable() {
@Override
public void run() {
while(true){
if(doIt){
System.out.println("done");
// try {
// Thread.sleep(10);
// } catch (InterruptedException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
}
}
}
});
public Test (){
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 450, 300);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
contentPane.setLayout(new BorderLayout(0, 0));
setContentPane(contentPane);
t.start();
addKeyListener(this);
contentPane.addKeyListener(this);
setVisible(true);
}
@Override
public void keyTyped(KeyEvent e) {}
@Override
public void keyPressed(KeyEvent e) {
if(e.getKeyCode() == KeyEvent.VK_UP){
doIt = true;
}
}
@Override
public void keyReleased(KeyEvent e) {
if(e.getKeyCode() == KeyEvent.VK_UP){
doIt = false;
}
}
public static void main(String[] args) {
new Test();
}
}
我认为您可以将外部doIt变量与“ Test.doIt”一起使用。
通常,您使用OuterClassName.this来引用外部类的封闭实例。
我猜您应该在thread()中尝试使用setter和局部变量。 这可能需要一个新的类。 因此,每次“ doit”更改时,您都会喜欢classname.setBool(doit)。 我不确定它是否正常工作,但是这将是一个不错的开始:)
我对线程不是很有经验,但是我会说“ doIt”不是线程安全的。
您还可以使用volatile : volatile private boolean doIt = false;
这样可以解决这个问题。 volatile使Java总是从内存中重新读取值,而不是缓存或其他内容。
但这就是我所知道的。 我希望有人能给出更好的解释。
我更喜欢AtomicBoolean,因为我一直读着这样的东西:“如果不需要,请不要使用volatile”,这就是AtomicBoolean的用途。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.