[英]what is the difference between delay and Thread.sleep in kotlin
I'm trying to figure out or to prove "how a delay is suspending function".我试图弄清楚或证明“延迟如何暂停功能”。
So, I wrote an example here所以,我在这里写了一个例子
var time: Long? = null
var job1 = GlobalScope.launch() {
println("Coroutine ${Thread.currentThread().name}")
time = measureTimeMillis {
Thread.sleep(1000)
println("After 1 seconds")
Thread.sleep(1000)
println("After 1 seconds")
Thread.sleep(1000)
println("After 1 seconds")
}
}
println("Thread ${Thread.currentThread().name}")
runBlocking {
job1.join()
println("Proccesed time is $time")
}
the Output I got is我得到的 Output 是
Thread main
Coroutine DefaultDispatcher-worker-1
After 1 seconds
After 1 seconds
After 1 seconds
Proccesed time is 3015
Then i replaced Thread.sleep
with delay
and still the processed time is 3045 ms
.然后我用
delay
替换了Thread.sleep
,处理时间仍然是3045 ms
。
I don't find any difference between Thread.sleep
with delay
.我发现
Thread.sleep
与delay
之间没有任何区别。
How to prove that it is a Suspending Function
and is different from Thread.sleep
如何证明它是一个
Suspending Function
并且与Thread.sleep
不同
The difference is that delay
is a suspend function that won't block the thread, while Thread.sleep()
will block the thread.不同之处在于
delay
是暂停 function 不会阻塞线程,而Thread.sleep()
将阻塞线程。
In other words, delay
means that the coroutine suspends for that amount of time, which in turn means that the underlying Thread
is free to go service a different coroutine which delays and suspends, and so on for all coroutines.换句话说,
delay
意味着协程暂停该时间量,这反过来意味着底层Thread
可以自由地为 go 服务另一个延迟和暂停的协程,等等所有协程。
With Thread.sleep
on the other hand, the underlying Thread cannot jump from coroutine to coroutine -- rather each Thread
is blocked until all the sleeps in the coroutine are over before it can go service the execution of another coroutine.另一方面,使用
Thread.sleep
,底层线程不能从协程跳转到协程——而是每个Thread
都被阻塞,直到协程中的所有睡眠都结束,然后它才能为另一个协程的执行提供服务。
To prove this to yourself with code, run a hundred of these coroutines instead of just 1. Then try it with a thousand.为了用代码向自己证明这一点,运行一百个这样的协程,而不是仅仅运行一个。然后用一千个试试。 The
Thread.sleep()
version will take longer and longer to execute because the default coroutine dispatcher thread pool is quickly used up. Thread.sleep()
版本的执行时间会越来越长,因为默认的协程调度器线程池很快就用完了。 On the other hand, the delay
version will execute in just over 3 seconds, because there are no calls blocking the coroutine threads.另一方面,
delay
版本将在 3 秒多一点内执行,因为没有调用阻塞协程线程。
fun main() {
var time: Long? = null
time = measureTimeMillis {
var jobs = (0..1_000).map {
GlobalScope.launch {
delay(1_000)
print(".")
delay(1_000)
print(".")
delay(1_000)
print(".")
/*
Thread.sleep(1_000)
print(".")
Thread.sleep(1_000)
print(".")
Thread.sleep(1_000)
print(".")
*/
}
}
runBlocking {
jobs.joinAll()
}
}
println("")
println("Processed time is $time")
}
When coroutine code runs as it should -- without blocking calls like Thread.sleep()
-- threads are always available to service coroutines that need to execute.当协程代码按应有的方式运行时——没有像
Thread.sleep()
这样的阻塞调用——线程始终可用于为需要执行的协程提供服务。 If there is no suspending equivalent available to a blocking call (for example, a 3rd party library that does synchronous I/O), always encapsulate those calls within a dispatcher designed to run such blocking calls eg withContext(Dispatchers.IO) {... }
, leaving the other coroutine dispatchers free to service non-blocking coroutines.如果没有可用于阻塞调用的挂起等效项(例如,执行同步 I/O 的第 3 方库),请始终将这些调用封装在旨在运行此类阻塞调用的调度程序中,例如
withContext(Dispatchers.IO) {... }
,让其他协程调度程序可以自由地为非阻塞协程提供服务。
Suspending a thread means that thread will "wait" doing something else in the meantime if necessary.挂起线程意味着线程将在必要时“等待”同时做其他事情。 Blocking a thread means that thread will wait doing nothing no matter what.
阻塞线程意味着线程无论如何都会等待。
You can prove that with this code:您可以使用以下代码证明这一点:
fun log(message: String) {
println("[${Thread.currentThread().name}] : $message")
}
fun main() {
runBlocking {
val myThread = newSingleThreadContext("My Thread")
launch(myThread) {
(1..3).forEach {
log("1st launch: $it")
//delay(1000)
Thread.sleep(1000)
}
}
launch(myThread) {
(1..3).forEach {
log("2nd launch: $it")
//delay(1000)
Thread.sleep(1000)
}
}
}
}
Output with delay
: Output 有
delay
:
[My Thread] : 1st launch: 1
[My Thread] : 2nd launch: 1
[My Thread] : 1st launch: 2
[My Thread] : 2nd launch: 2
[My Thread] : 1st launch: 3
[My Thread] : 2nd launch: 3
Output with Thread.sleep
: Output 与
Thread.sleep
:
[My Thread] : 1st launch: 1
[My Thread] : 1st launch: 2
[My Thread] : 1st launch: 3
[My Thread] : 2nd launch: 1
[My Thread] : 2nd launch: 2
[My Thread] : 2nd launch: 3
Since delay
is a suspending function it can be called only from inside a coroutine or from another suspending function.由于
delay
是一个暂停的 function,它只能从协程内部或另一个暂停的 function 调用。
I only will try to answer in a very simple way.我只会尝试以非常简单的方式回答。
fun main() = runBlocking<Unit> {
launch {
Thread.sleep(3000L)
// delay(3000L)
println("Coroutine 1 ${Thread.currentThread().name}")
}
launch {
println("Coroutine 2 ${Thread.currentThread().name}")
}
}
Using Thread.sleep
使用 Thread.sleep
runBlocking
to wrap the execution of the main function.runBlocking
来封装主function的执行。 Which allows me to use launch
keyword directly as it runs on context of runBlocking
.launch
关键字,因为它在runBlocking
的上下文中运行。launch
coroutine will run on the main
Thread. launch
协程都将在main
线程上运行。 Which can be seen by printing the thread name.Thread.sleep(3000L)
is put inside first launch.Thread.sleep(3000L)
放入第一次启动时。 The output is Coroutine 1 main
Coroutine 2 main
This is because, when first coroutine is executed it will come at Thread.sleep(3000L) which in turns block the main thread.这是因为,当第一个协程执行时,它将进入 Thread.sleep(3000L) ,这反过来又阻塞了主线程。 So, main thread is blocked and it will not handle other threads for 3 seconds.
因此,主线程被阻塞,它不会处理其他线程 3 秒。
Then after 3 seconds Coroutine 1 main
will get printed.然后在 3 秒后
Coroutine 1 main
将被打印出来。 and then Coroutine 2 main
will be printed然后将打印
Coroutine 2 main
Using delay
使用延迟
Thread.sleep(3000L)
by delay(3000L)
delay(3000L)
替换Thread.sleep(3000L)
3000L)Coroutine 2 main
first.Coroutine 2 main
。Coroutine 1 main
Coroutine 1 main
Coroutine 2 main
Coroutine 1 main
Hence, we can prove that Thread.sleep
will blocking the thread, whereas delay
is just suspending the thread.因此,我们可以证明
Thread.sleep
会阻塞线程,而delay
只是暂停线程。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.