所以我遇到了一个问题,我无法理解为什么在主测试文件中看不到实现ActionListener的内部类中其他类设置的静态变量。
下面是我遇到问题的三个文件。在Verification类中更改静态变量标志的预期操作应该终止程序,但它不会。
InnerClassTest File(Main class file)
package innerClass;
public class InnerClassTest
{
public static void main(String[] args)
{
TalkingClock clock = new TalkingClock(2000, true);
clock.start();
while(true)
{
if(Verification.flag == true)
{
System.exit(0);
}
if (TalkingClock.flag == true)
{
System.exit(0);
}
}
}
}
package innerClass;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.Timer;
public class TalkingClock
{
private int interval;
private boolean beep;
public static boolean flag = false;
public TalkingClock(int interval, boolean beep)
{
this.interval = interval;
this.beep = beep;
}
public void start()
{
ActionListener listener = new TimePrinter();
Timer t = new Timer(interval, listener);
t.start();
}
public class TimePrinter implements ActionListener
{
@Override
public void actionPerformed(ActionEvent event)
{
Date now = new Date();
System.out.println("At the tone, the time is " + now);
if (beep) Toolkit.getDefaultToolkit().beep();
Verification.flag = true;
flag = true;
}
}
}
package innerClass;
public class Verification
{
public static int count = 0;
public static boolean flag = false;
}
答案 0 :(得分:1)
这是因为多线程问题,而不是内部类或静态变量。
您正在从多个不同的线程访问/修改flag
,但没有告诉编译器它需要确保正确更新该值以反映其他线程上的更改。
Java编程语言允许线程访问共享变量(第17.1节)。通常,为了确保共享变量的一致性和可靠性更新,线程应确保通过获取锁定来独占使用此类变量,通常会对这些共享变量实施互斥。
Java编程语言提供了第二种机制volatile字段,比某些用途的锁定更方便。
字段可以声明为volatile,在这种情况下,Java Memory Model可以确保所有线程都看到变量的一致值
如果没有该关键字,JVM和编译器可以自由地进行优化,这些优化不允许其他线程进行更改。点击flag
volatile
即可解决问题。