2014-10-14 5 views
0

Я столкнулся с чем-то путаным с моим поведением кода в моей операционной системе. Теперь вы все знаете, что есть много способов сделать синхронизацию для многопоточности, чтобы получить правильное значение независимо от того, что!Почему мой код работает отлично, не используя синхронизацию ..?

так как получилось, что я всегда получаю правильное значение без использования синхронизированного пути ??? !!!

, например, посмотреть в коде ниже

В регулярном поведении ниже программы должны прекращено после нескольких второй .. как есть десять нитей, обращающиеся ту же самую переменную и увеличиваем его на один .. и это должно привести чтобы в некоторых случаях иметь значение count, отличное от 100000 .. и это остановит цикл. Я запускаю этот код за 20 минут .. и он отлично работал ..

может кто-нибудь сказать мне, что происходит : D ??

моя операционная система Виндоус 7, и я использую затмение Kepler .. виртуальная машина является 8 .. и мой процессор не Dual Core .. это обычный соло .. с 2.4 GHZ ...

public class Worker { 
    int count; 

    public static void main(String[] args) { 
     new Worker().run(); 
    } 

    public void run() { 
     do { 
      count = 0; 
      Thread thread1 = new Thread(new Runnable() { 
       public void run() { 
        for (int i = 0; i < 10000; i++) { 
         count++; 
        } 
       } 
      }); 

      Thread thread2 = new Thread(new Runnable() { 
       public void run() { 
        for (int i = 0; i < 10000; i++) { 
         count++; 
        } 
       } 
      }); 

      Thread thread3 = new Thread(new Runnable() { 
       public void run() { 
        for (int i = 0; i < 10000; i++) { 
         count++; 
        } 
       } 
      }); 

      Thread thread4 = new Thread(new Runnable() { 
       public void run() { 
        for (int i = 0; i < 10000; i++) { 
         count++; 
        } 
       } 
      }); 

      Thread thread5 = new Thread(new Runnable() { 
       public void run() { 
        for (int i = 0; i < 10000; i++) { 
         count++; 
        } 
       } 
      }); 

      Thread thread6 = new Thread(new Runnable() { 
       public void run() { 
        for (int i = 0; i < 10000; i++) { 
         count++; 
        } 
       } 
      }); 

      Thread thread7 = new Thread(new Runnable() { 
       public void run() { 
        for (int i = 0; i < 10000; i++) { 
         count++; 
        } 
       } 
      }); 

      Thread thread8 = new Thread(new Runnable() { 
       public void run() { 
        for (int i = 0; i < 10000; i++) { 
         count++; 
        } 
       } 
      }); 

      Thread thread9 = new Thread(new Runnable() { 
       public void run() { 
        for (int i = 0; i < 10000; i++) { 
         count++; 
        } 
       } 
      }); 

      Thread thread10 = new Thread(new Runnable() { 
       public void run() { 
        for (int i = 0; i < 10000; i++) { 
         count++; 
        } 
       } 
      }); 

      thread1.start(); 
      thread2.start(); 
      thread3.start(); 
      thread4.start(); 
      thread5.start(); 
      thread6.start(); 
      thread7.start(); 
      thread8.start(); 
      thread9.start(); 
      thread10.start(); 

      try { 
       thread1.join(); 
       thread2.join(); 
       thread3.join(); 
       thread4.join(); 
       thread5.join(); 
       thread6.join(); 
       thread7.join(); 
       thread8.join(); 
       thread9.join(); 
       thread10.join(); 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 

      System.out.println("Count is: " + count); 
     } while (count == 100000); 
    } 
} 
+0

@wrongAnswer: добавление переменной из нескольких потоков без каких-либо операций, чтобы гарантировать, что приращение атомарно или что оно работает с последним значением переменной. –

ответ

2

Я пробовал ваш код, и он заканчивается сразу после одной итерации в моей системе! (Таким образом, я доказал, что он ошибочен одним простым запуском - вы не можете доказать, что это правильное событие, когда вы запускаете его навсегда).

Это обратный знак параллелизма: вы не можете даже ошибочно полагаться на неправильный код.

Я предполагаю, что ваша одноядерная система может быть «проблемой»: ваши потоки не работают параллельно, вместо этого они запускаются последовательно, поэтому ожидаемых условий гонки не возникает.

+0

То же, что я думаю, проблема .. что ожидаемых условий гонки не происходит .. потому что это одна основная система .. спасибо чувак ..! –

+2

@Waseem: даже на одной базовой системе он * может ошибаться, из-за предпосылки. Это будет смесь этого, модель памяти и JIT-скомпилированный код. –

+0

@JonSkeet, так что же тогда произошло? Я пробежал код в течение 20 минут, и это не закончилось. –

5

Я подозреваю, что ваш JVM случается сгенерировал код, где count++является JIT-компилируются в атомарные операции ... даже если это не гарантировано ... а модель памяти компьютера не так слаба, как это могло быть.

Это все еще небезопасно - это просто, что вам удастся избежать этого в вашей архитектуре.

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