以下是我创建的对象的两种方法。父类(super class)已实现 MouseListener。
@Override public void mousePressed(MouseEvent event){
mIsPushed = true;
System.out.println("Button pushed");
}
@Override public void mouseReleased(MouseEvent event){
mIsPushed = false;
System.out.println("Button released");
}
当两个 System.out.println
调用取消注释时,程序可以正常工作并按其应有的方式运行。当它们不存在时,它什么也不做。我什至在 mIsPushed
赋值处放置了断点,但从未到达它们。
但是,如果我在调用这两个函数的地方放置一个断点,调试器就会到达它并进行调用。
谁能告诉我我错过了什么?
最佳答案
这可能是由于不同的线程缓存了自己的 mIsPushed
变量值。
您需要同步对此变量的访问。您有几种不同的选择:
- 将其声明为
volatile
- 使用
java.util.concurrent
包中的一些高级构造(例如AtomicBoolean
) - 使用
synchronized
关键字同步对变量的访问。
更详细地说:Java 内存模型不保证从一个线程读取变量会产生从另一个线程写入该变量的最后一个值。这是为了允许 JVM 优化 Java 程序的执行。添加 System.out.println 可能会刷新缓存并导致在需要时加载新值。
要明确告诉 JVM 确保不应该使用缓存值,您需要在写入和读取之间引入“发生之前”关系。
进一步阅读:
关于仅当调用 System.out.println 时才会调用 Java 重写方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8040821/