2016-07-12 3 views
0

У меня возникла проблема в том, что я не могу понять, почему статическая переменная другого класса внутри внутреннего класса, реализующего ActionListener, не отображается в основном тестовом файле.Статическая переменная не может быть установлена ​​внутри внутреннего класса

Ниже приведены три файла, с которыми у меня возникает проблема. Ожидаемое действие изменения статического символа переменной в классе проверки должно завершать программу, но это не так.

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


TalkingClock File

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; 
     } 
    } 
} 

Verification Class File

package innerClass; 

public class Verification 
{ 
    public static int count = 0; 
    public static boolean flag = false; 
} 
+1

Важно, чтобы вся соответствующая информация для вопроса находилась в вопросе, а не только в ссылках. Пожалуйста, сохраните этот код в вопросе. – 4castle

+0

Ваш код многопоточен (с помощью таймера) и не синхронизирован должным образом. Нет никаких оснований ожидать, что один поток увидит любые записи, выполненные другим. –

+5

Попробуйте сделать флаг изменчивым. – shmosel

ответ

1

Это из-за многопоточности вопросов, а не внутренних классов или статических переменных.

Вы получаете доступ/изменение flag из нескольких разных потоков, но не сообщают компилятору, что ему необходимо убедиться, что значение правильно обновлено, чтобы отражать изменения в других потоках.

От JLS section 8.3.1.4:

Язык программирования Java позволяет потокам получить доступ к общим переменным (§17.1). Как правило, для обеспечения постоянного и надежного обновления общих переменных поток должен гарантировать, что он имеет исключительное использование таких переменных, получая блокировку, которая, как правило, обеспечивает взаимное исключение для этих общих переменных.

Язык программирования Java предоставляет второй механизм, изменчивые поля, который более удобен, чем блокировка для некоторых целей.

Поле может быть объявлено нестабильным, и в этом случае модель памяти Java гарантирует, что все потоки видят одинаковое значение для переменной

Без этого ключевого слова, виртуальная машина и компилятор свободны делать оптимизации, которые дон 't допускать изменения другими потоками. Сделайте flagvolatile и проблема будет исправлена.

+0

Большое спасибо за подробный ответ –

Смежные вопросы