线程未按顺序依次运行

我期望输出为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 ,锁定,信号量等)。

改成

 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
。 。 。