2013-08-31 2 views
1

Я хочу, чтобы обе нити, чтобы разделить переменную, но иногда во время выполнения он печатает 2 раза, а не 1 и 2.Темы разделяющей переменного экземпляра

public class man implements Runnable{ 

    int value = 0; 

    public static void main(String[] args){ 
     Runnable job = new man(); 
     Thread work1 = new Thread(job); 
     work1.setName("Thread1"); 
     Thread work2 = new Thread(job); 
     work2.setName("Thread2"); 

     work1.start(); 
     work2.start(); 
    } 


    public void run(){ 
     synchronized(this){ 
      value = value + 1; 
     } 
     System.out.println("VALUE = " + value +", Running " + Thread.currentThread().getName()); 
    } 



} 

Выход иногда:

VALUE = 2, Running Thread2 
VALUE = 2, Running Thread1 

и другие времена это:

VALUE = 1, Running Thread2 
VALUE = 2, Running Thread1 

Почему это происходит? Я изучаю Java в книге HeadFirst, и этот вопрос возник.

ответ

3

Вы не синхронизируете доступ в вызове System.out.println, поэтому иногда «второй» поток увеличивается до того, как печатает «первый поток».

+0

О хорошо, спасибо за подсказку. –

3

Вам необходимо синхронизировать доступ к переменной.

Что происходит, так это то, что оба потока считывают значение переменной после того, как оба увеличили его. Другими словами:

  1. резьбы 1: синхронизирована (это) => резьбы 2 не может войти в свою собственную синхронизирована (это)
  2. резьбы 1: = значение + 1; => Говорят 1
  3. Тема 1: Заканчивается синхронизирована блок => Тема 2 может войти в свой собственный синхронизирована (это) в настоящее время
  4. Тема 2: синхронизирована (это) => Тема 1 не может войти в свои синхронизирована (это)
  5. Резьба 2: значение = значение + 1; => 2
  6. резьбы 2: значение печатает, т.е. 2
  7. резьбы 1: значение печатает, т.е. 2

Решение состоит в том, чтобы переместить System.out.println("VALUE = " + value +", ...); внутри synchronized блока. Это заставляет переупорядочения последовательности сверху в:

  1. Тема 1: синхронизирована (это) => резьбы 2 не может войти в свою собственную синхронизирована (это)
  2. резьбы 1: = значение + 1; => Скажет 1
  3. Темы 1: значение принтов, то есть 1
  4. резьбы 1: Концы синхронизирована блок => Тема 2 может войти в своем собственном синхронизирована (это) в настоящее время
  5. Тема 2: синхронизировано (это) => Нить 1 не может войти в свой собственный синхронизированный (это)
  6. Тема 2: значение = значение + 1; => 2
  7. Тема 2: значение принтов, то есть 2
Смежные вопросы