Потоки, выполняемые последовательно

Я ожидал выхода 0 0 1 1 2 2 … но выход был 0 1 2 3 … 0 1 2 3

class Runner: Thread() { override fun run() { var i = 0 while (i < 10) { println("${Thread.currentThread().name} $i") i++ } try { Thread.sleep(100) } catch (e: Exception) { e.printStackTrace() } } } fun main(args: Array<String>) { val nah = Runner() val blah = Runner() nah.start() blah.start() } 

Что неверно?

    Ну, вывод этого кода может быть в основном любой чередующейся версией чисел двух потоков. Они будут индивидуально печатать цифры от 1 до 10 в последовательности, но нет никакой гарантии, когда это происходит по отношению друг к другу, поскольку между ними нет синхронизации, и без задержки внутри цикла они оба просто пытаются чтобы напечатать числа как можно быстрее.

    Все это вполне допустимые результаты для этого кода:

     T1 1 2 3 T2 1 2 3 out 1 1 2 2 3 3 T1 1 2 3 T2 1 2 3 out 1 2 3 1 2 3 T1 1 2 3 T2 1 2 3 out 1 2 3 1 2 3 T1 1 2 3 T2 1 2 3 out 1 1 2 3 2 3 

    Если вы положите задержку внутри цикла, и это достаточно долго, вы в некоторой степени гарантируете, что вы получите последовательность, подобную 1 1 2 2 3 3 , но порядок, в котором две копии номера печатаются между потоками, по-прежнему до того, как потоки получат запланированное выполнение в конкретном прогоне.

      < ~100 ms > T1 1 2 3 T2 1 2 3 out 11 22 33 T1 1 2 3 T2 1 2 3 out 11 22 33 T1 1 2 3 T2 1 2 3 out 11 22 33 

    Обратите внимание, что Thread.sleep сам по себе не совсем точный , и использование его для этой цели просто будет работать большую часть времени, если вы заложите здесь достаточно долгую задержку.

    Если вы хотите написать многопоточный код, который работает предсказуемо, посмотрите на различные методы synchronized ( synchronized , блокировки, семафоры и т. Д.).

    Изменить на

     class Runner: Thread() { override fun run() { var i = 0 while (i < 10) { println("${Thread.currentThread().name} $i") i++ try { Thread.sleep(100) } catch (e: Exception) { e.printStackTrace() } } } } 

    Может быть, это близко к вам, но этот результат не всегда есть.

    T1 1
    T2 1
    T1 2
    T2 2
    T1 3
    T2 3
    , , ,