В вашем коде первая проблема заключается в том, что ресурс блокировки должен быть конечным объектом, поэтому объявите его следующим образом:
final Integer lock = new Integer( 0 );
Поскольку без этой семантики разные потоки могут блокироваться для другого объекта, однако работая на том же объекте.
И объяснение поведению, которое вы наблюдали.
Хотя целью может быть повышение общей производительности, использование нескольких потоков всегда приводит к некоторым затратам производительности по сравнению с однопоточным подходом. К ним относятся издержки, связанные с координацией между потоками (блокировка, сигнализация, синхронизация), повышенное переключение контекста, создание и удаление потоков и накладные расходы по планированию. ref.ch-11.1
Как уже говорилось, блокировка, переключение контекста и сигнализация связаны с многопоточностью по сравнению с однопоточными программами. В вашем случае причина, по которой вы получаете последовательность «0321», не воспроизводится, например, на другом компьютере.
Метод Thread.start()
вызывает системный собственный метод start0
, и система выделяет ресурсы, и если поток блокирует любые ресурсы (что он делает). Поскольку вашему методу требуется время (хотя и небольшое), чтобы завершить метод run()
, другие потоки ожидают
Простая разница, изменяющая ваш код на этот, приведет к другому выводу. Поскольку это вводит различия во времени и планировании того, какой поток процессор возобновляет и получает следующую блокировку на Integer lock
. Короче говоря, это не воспроизводимый вывод, и он будет отличаться в 1001 попытка «может быть».
final Integer lock = new Integer( 0 );
for ( int i = 0; i < 4; i++ ) {
System.out.println("starting : " + i);
new Locks1( lock, i ).start();
}
выходы:
starting : 0
starting : 1
Thread #0 is tired
Thread #0 is rested
Thread #0 is tired
Thread #0 is rested
Thread #0 is tired
Thread #0 is rested
Thread #1 is tired
Thread #1 is rested
Thread #1 is tired
Thread #1 is rested
Thread #1 is tired
Thread #1 is rested
starting : 2
Thread #2 is tired
Thread #2 is rested
Thread #2 is tired
Thread #2 is rested
Thread #2 is tired
Thread #2 is rested
starting : 3
Thread #3 is tired
Thread #3 is rested
Thread #3 is tired
Thread #3 is rested
Thread #3 is tired
Thread #3 is rested
ПРИМЕЧАНИЕ. Это опять может не воспроизводиться в вашей машине.