2016-06-07 4 views
1

Я пытаюсь считать 100 номеров многопоточными и однопоточными. Поскольку синхронизируемое ключевое слово разрешает только один поток за раз (это похоже на один поток), поэтому эти два метода ниже должны иметь одинаковую рабочую среду приблизительно, если мы игнорируем влияние времени на создание и синхронизацию потоков?Синхронизированная многопоточность против одной нити

Многопоточность с использованием синхронизировано:

public synchronized static void increment() { 
    sum++; 
} 

public static void main(String[] args) { 
    Thread t1 = new Thread(new Runnable() { 
     @Override 
     public void run() { 
      for (int i = 0; i < 50; i++) { 
       increment(); 
      } 
     } 
    }); 
    Thread t2 = new Thread(new Runnable() { 
     @Override 
     public void run() { 
      for (int i = 0; i < 50; i++) { 
       increment(); 
      } 
     } 
    }); 
    t1.start();; 
    t2.start(); 
    try { 
     t1.join(); 
     t2.join(); 
    } catch (InterruptedException e) { 
     e.printStackTrace(); 
    } 
    System.out.println(sum); 

однопоточную:

public static void main(String[] args) { 
    for (int i = 0; i < 100; i++) { 
     sum++ 
    } 

    System.out.println(sum); 
} 
+0

Что такое 't1' во втором подходе? Вы имеете в виду 't3'? –

+0

да. Я отредактировал его. @AndyTurner – SHE

+0

«Однопоточность с использованием синхронизации:« На самом деле, это многопоточность. У вас есть основной поток и 't3'. И вы не используете 'synchronized'. –

ответ

1

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

+0

Если мы игнорируем влияние времени на создание и синхронизацию потоков, их время работы должно быть примерно одинаковым? @Scott Twombly – SHE

+0

Конечно, но я думаю, что это неразумно делать это. Вы не можете отделить jvm от java. Если вы хотите просто подсчитать количество раз, когда число увеличивается, они, конечно, одинаковы в обоих сценариях, но это почти бессмысленная метрика. Есть еще много «вещей» и методы, которые вызывают под капотом, в вашем многопоточном примере, игнорируя их, заставляет меня задуматься, в чем смысл сравнивать эти вещи в первую очередь? @SHE –

+0

@SHE, вам не хватает точки Томаса Клегера (см. Его комментарий к вашему вопросу, выше). Хороший компилятор мог распознать, что 'sum', вычисленный вашим однопоточным примером, не зависит от какой-либо переменной, от любого вызова функции, на любом входе. Это просто постоянный. Это 4950, и всегда будет 4950. Хороший компилятор может заменить весь цикл «sum = 4950;», и это не изменит результат работы программы, но это заставит его работать намного быстрее. Но компиляторы не могли сделать это для многопоточной версии. Слишком сложно. –

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