2

The comment in example code says delay() is non-blocking. Should it be suspending ?

https://kotlinlang.org/docs/reference/coroutines/basics.html

fun main() {
    GlobalScope.launch { // launch new coroutine in background and continue
        delay(1000L) // non-blocking delay for 1 second (default time unit is ms)
        println("World!") // print after delay
    }
    println("Hello,") // main thread continues while coroutine is delayed
    Thread.sleep(2000L) // block main thread for 2 seconds to keep JVM alive
}
user1443721
  • 1,110
  • 2
  • 14
  • 33
  • It is a correct description because it does not block any thread, it just suspends the current coroutine. – Salem Mar 24 '19 at 19:15
  • non-blocking is a well defined term in Computer Science. The println("World!") would be run immediately, instead of waiting for 1 second, based on the definition. Don't use this term if your meaning is different. – user1443721 Mar 25 '19 at 04:32
  • My meaning is definitely not different, I don't see what you're trying to say. Delay is not a blocking call, as I just explained. – Salem Mar 25 '19 at 05:32
  • @Moira: delay is suspending and non-blocking. Joffrey has answered it. it is not "non-blocking" only. – user1443721 Mar 25 '19 at 23:05
  • @Moira: as you said, "it just suspends the current coroutine". Why does the comment for the delay call not say so? Instead, the comment is "non-blocking". Is it not misleading? – user1443721 Mar 26 '19 at 04:34
  • No. You need to understand that coroutines are essentially glorified callbacks (and are compiled as such.) A callback that is scheduled in 2000 ms does not block any thread, unlike `Thread.sleep` for example (it is therefore non-blocking), it simply "suspends" the coroutine. Execution of the current coroutine is paused until the suspension point is reached. Coroutines are not the same as threads and the documentation appropriately does not treat them as such, even if the end result is similar. – Salem Mar 26 '19 at 07:09
  • suspending and blocking are two different things. – Shubham AgaRwal May 05 '20 at 14:24

1 Answers1

12

delay is suspending and non-blocking.

TL;DR: delay does have the effect of "waiting" before executing the statement that follows it in the current coroutine. Non-blocking simply means that during this wait, the current thread can do something else.


The Kotlin documentation often says "non-blocking" for suspending functions to make it clear that they don't block the current thread, but instead simply suspend the current coroutine.

It may be misleading sometimes because "non-blocking" places the emphasis on the fact that nothing is blocked, while it should still be made clear that suspending functions do suspend the current coroutine (so at least something is kinda blocked, even if the thread itself carries on).

The fact that they suspend the current coroutine make these functions appear synchronous from the point of view of the current coroutine, because the coroutine needs to wait for these functions to complete before executing the rest of the code. However, they don't actually block the current thread because their implementation uses asynchronous mechanisms under the cover.

Joffrey
  • 32,348
  • 6
  • 68
  • 100
  • 1
    Thanks! Your answer is reasonable. "non-blocking" here is really misleading. The formal document should not use this well defined term for something else. Coroutine is a new feature. It is worth to define a new set of terms to explain the features. – user1443721 Mar 25 '19 at 04:41
  • @user1443721 FWIW this terminology is not new to asynchronous programming at all; see the [C# docs](https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/async/#BKMK_Threads) for example. – Salem Mar 25 '19 at 06:31
  • 1
    @user1443721 That's exactly what Kotiln did. The new terminology is "suspending" while the old terminology ("blocking") keeps the old meaning and still refers to threads. – Marko Topolnik Mar 25 '19 at 07:37
  • @Moira: non-blocking has been well defined, even earlier than C#. check the answer to this question, https://stackoverflow.com/questions/10570246/what-is-non-blocking-or-asynchronous-i-o-in-node-js – user1443721 Mar 26 '19 at 03:32
  • @Marko Topolnik: "suspending" is not new terminology. It has been used to describe thread life cycle. My question is mainly on the comment for delay() function in the example. – user1443721 Mar 26 '19 at 04:29
  • @user1443721 that is exactly my point. Non-blocking has been used (especially in the context of asynchronous operations) for a long time. – Salem Mar 26 '19 at 07:06
  • @user1443721 Inside the JVM, "suspend" was used for the method `Thread.suspend()`, which was never implemented and has been deprecated for 20 years now. I think you'll be able to get used to its meaning with respect to coroutines without confusing it with the non-existent thread suspension. Neither I nor anyone I saw writing about it raised the concern of ambiguity. Also, every language/environment uses the same terms with slightly different meanings, this is a well-known phenomenon. It is not common practice to invent new words in each environment. – Marko Topolnik Mar 26 '19 at 08:22
  • @Marko Topolnik: You acknowledge the term is ambiguity. Is it better to write a more clear comment to help readers to understand? The example is "Your first coroutine" in the basic category. That means the readers are the beginner to coroutine. – user1443721 Mar 26 '19 at 15:09
  • @Moira: but you have to realize "Non-blocking" has no meaning "suspending". That is the point. – user1443721 Mar 26 '19 at 15:12
  • @user1443721 You are correct, but the function is a suspend function, so I guess it would be redundant. I didn't write the documentation, but I suppose that this, combined with the fact that the result of calling delay is somewhat obvious, led to this not being mentioned in the documentation. – Salem Mar 26 '19 at 15:16
  • @Moira: Again, this is "Your first coroutine". The reader has no knowledge what "delay()" is. – user1443721 Mar 26 '19 at 15:19
  • @Marko Topolnik: It is not necessary to have Thread.suspend(). A blocked thread is in the suspending status. Java has another method yield() which can send the thread to be suspended too. – user1443721 Mar 26 '19 at 15:21
  • @user1443721 I think now you're talking about task suspension on the level of OS preemptive multitasking, so you're using a completely different frame of reference. However, when the OS pre-empts the native thread that runs a given Java thread, the Java thread's state remains `RUNNABLE`. – Marko Topolnik Mar 26 '19 at 16:15
  • if Dispatchers.Main is used to launch a coroutine using launch(Dispatchers.Main){ delay(1000)}, does delay run on main thread or is it run on some background thread? – Hari Kiran Jul 24 '20 at 02:26
  • @HariKiran I think you could say that `delay()` doesn't "run" anywhere. The coroutine started by `launch` is executed on the main thread, then reaches `delay()` which suspends this coroutine. This means the main thread can go execute some other code, while waiting for this delay to finish, and then the launched coroutine can resume executing the code after `delay()` in the main thread. I believe the wait and the moment the coroutine is resumed is handled by the Dispatcher itself, but I don't know the internals of it. – Joffrey Feb 19 '21 at 15:43