2015-02-08 3 views
1

В процессе обучения Java параллелизма я столкнулся с таким поведением, которое я не могу объяснить:Java Многопоточность нитей, заканчивающиеся в произвольном порядке

public class ThreadInterferrence implements Runnable { 

    public static void main(String[] args) throws InterruptedException { 
     Thread t = new Thread(new ThreadInterferrence()); 
     t.start(); 
     append("1", 50); 
     t.join(); 
     System.out.println(value); 
    } 

    private static String value = ""; 

    public void run() { 
     append("2", 50); 
    } 

    private static void append(String what, int times) { 
     for (int i = 0; i < times; ++i) { 
      value = value + what; 
     } 
    } 
} 

Почему программа генерации случайных строк? Что еще более важно Почему длина вывода зависит от? разве не всегда должно быть ровно 100 символов?

примеры вывода:

22222222222222222222222222222222222222222222222222 
1111111111111111111111111111112121112211221111122222222222222 

и т.д ..

ответ

3

На теме обновленного вопроса (почему длина выхода меняется? Не должен всегда быть ровно 100 символов?)

поведение будет непредсказуемым, так как повторное присвоение новой строки не является атомарным. Обратите внимание, что Строки неизменяемы, и вы продолжаете присваивать значение переменной. Итак, что происходит, один поток получает значение, другой поток также получает значение, один поток добавляет символ и записывает его снова, но также делает другой поток со старым значением. Теперь вы теряете данные, потому что обновление из одного из потоков теряется.

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

4

Причина в том, у вас есть две темы.

  • Основной поток, который добавляя к строке же значение
  • ThreadInterferrence Thread, который снова добавляя к такому же значению String.

Это операционная система (ОС), которая планирует, какой поток запускать, когда и, следовательно, вы видите случайный выход. Таким образом, в вашем случае ОС планирует запустить вашу систему на время, которая печатает 1, а затем пытается запустить основную нить, которая, в свою очередь, печатает 2.

+0

Хорошо, что я до сих пор слежу за вами. Но почему размер выходной строки меняется? Разве не должно быть ровно 100 символов независимо от последовательности? –

1

[Вопрос] Что еще более важно, почему длина выходного сигнала меняется?

[Ответить] Переменная «значение» используется несколькими потоками (основной поток, а также другой поток). Следовательно, метод, который используется для изменения состояния переменной, должен быть потокобезопасным для контроля конечной длины. Это не так.