我预计输出为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()
}
什么是不正确的?
答案 0 :(得分:2)
嗯,这段代码的输出基本上可以是两个线程的任何交错版本。数字。它们都按顺序分别打印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
本身isn't perfectly accurate,并且如果你在这里投入足够长的延迟,大部分时间都会使用synchronized
。
如果要编写可预测运行的多线程代码,请查看不同的同步方法(DataSet ds = getDataSet();
,锁,信号量等)。
答案 1 :(得分:0)
更改为
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
。 。