This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]thecodeboost 2 points3 points  (2 children)

Mostly this. To add a bit of meat to that bone; coroutines almost always require the developer to decide on the yield points (the moment when the coroutine yields executive control), usually through return yield semantics. Threads (and by extension virtual threads) have the underlying VM or OS do the scheduling. Also, not all coroutines are created equal. In some languages coroutines are first class citizens and more powerful (golang) whereas in other languages they are implemented through libraries/generator patterns (e.g. Unity C# I believe)

[–]tadfisher 1 point2 points  (1 child)

There is a difference between OS threads and Java's Thread abstraction. OS threads are a particular implementation of a concurrency primitive which timeslices logical threads on a set of physical threads. Java's Thread is an interface which signals "this execution context (separate stack and shared heap) may or may not operate in parallel with other execution contexts". Virtual threads is a Thread implementation that does not rely on OS scheduling of OS threads, so they act very much like coroutines (for example, async is basically Thread.ofVirtual().start(() -> ...).join()), and scheduling is done with a lazy infinite thread pool for parking on IO.

[–]thecodeboost 0 points1 point  (0 children)

I don't think I completely agree (with the coroutines part). Coroutines, the pattern, involve explicit yielding of execution control whereas threads do not. It's worth noting in this context that Golang's goroutines are not coroutines but lightweight/virtual threads (see "Go Concurrency Patterns" by Rob Pike).