2014-12-31 7 views
1

Я работаю над проектом с потоками. Это начало моего основного класса.Невозможно присвоить значение статическому целому

public class Main { 
    public static int firstIndex, secondIndex, thirdIndex, fourthIndex, fifthIndex; 

Затем я создаю поток и переопределяю его функцию run(). Внутри run() я пытаюсь назначить целые числа моим статическим целочисленным переменным, которые я определил ранее.

cThread thread1 = new cThread(ant) { 
      @Override 
      public void run() { 
       try { 
        firstIndex = myAllocator.alloc(11, '1', this); 
        secondIndex = myAllocator.alloc(10, '2', this); 

Функция Alloc() возвращает правильные целые числа внутри, но статические переменные всегда остаются на 0 и не изменится до значений, что функция возвращает. Однако, если я не делаю целые статичен, он дает следующее сообщение об ошибке:

Cannot make a static reference to the non-static field firstIndex. 

Я уверен, что функции возвращают правильные значения. В чем проблема? Большое спасибо.

+2

Попробуйте Main.firstIndex. – miljanm

+0

Это не сработало, нет синтаксической ошибки, но она по-прежнему остается равной 0. Она также не позволит мне перейти от статического к нормальному целому. –

+3

Пожалуйста, ** пожалуйста **, ** ПОЖАЛУЙСТА ** прочитайте документацию _some_ о том, как потоковая обработка работает на Java. У вас нет синхронизации и нет 'volatile'. Неудивительно, что ваш код не работает. –

ответ

2

Проверьте следующие вещи:

  • что вы работаете нить. thread1.start()
  • То, что вы проверяете статические переменные после завершения потока. После того, как все потоки будут выполняться параллельно, чтобы вы могли проверять значения до того, как поток имел возможность запускать.
  • Вам нужна синхронизация. Либо сделайте статические переменные volatile, либо заверните свой логин в методе run потока с блоком synchronized. При чтении вам также потребуется использовать синхронизированный блок. Возможно, что значения правильно заданы одним ядром, но другой Core пытается их прочитать. Без синхронизации у вас нет гарантии, что оба ядра будут видеть правильные данные. (из-за кеширования и т. д.)
+0

Да, теперь это исправлено. По-видимому, я пытался использовать целые числа, которые я бы приобрел до того, как поток был завершен, поэтому ему никогда не приходилось назначать. : [ –

+0

'volatile' - чрезвычайно слабая форма синхронизации.Если вы хотите, чтобы один поток обновлял переменную и другой поток читал обновленное значение; 'volatile' будет гарантировать, что значение передается от одного потока к другому, но только в том случае, если чтение действительно происходит после записи. Использование 'volatile' ничего не делает, чтобы убедиться, что чтение не произойдет _ before_ write. Вам нужно 'wait()' и 'notify()', или вам нужна конструкция более высокого уровня, построенная на примитивах wait/notify, чтобы гарантировать, что чтение и запись происходят в правильном порядке. –

+0

@james large - 'volatile' - это всего лишь механизм синхронизации, такой как' synchronized'. Он не гарантирует ничего о порядке чтения/записи. Это остается для разработчика в зависимости от их желаемой логики. Они могут иметь несколько операций чтения/записи и, возможно, не нуждаются в том, чтобы ждать чего-либо, и это может быть действительно для их использования. Тем не менее, 'volatile' гарантирует, что вы получите действительное старое или новое значение и ничего между ними. –

2
  1. Если вы назначаете значения из нового потока, вы должны дождаться завершения потока перед чтением значений.

  2. Ожидая, что записи, которые просматриваются при чтении в разных потоках, требуют синхронизации потоков. Определите переменные как изменчивые или защитите их блокировкой.

0

Не ставьте переменные в статические; Таким образом, вы должны изменить вашу первую строку кода на

public int firstIndex, secondIndex,... 
Смежные вопросы