That's true. I come from the threaded runtimes where we can just block the thread because there's always another thread that can take over. I think that if I try to approach this from a perspective of a single-threaded environment, I might get closer to grasping it.
> The problem is that many environments are effectively non-multi-threaded, especially the (usually single) thread/queue/process that draws the UI and responds to user input
Can you elaborate on why "especially" UI threads/queues/processes are "usually single"?
> Can you elaborate on why "especially" UI threads/queues/processes are "usually single"?
I don't think there's a particularly insightful answer to this question here, it's just that UI frameworks are almost universally written with the assumption that they are only used from one thread. UI frameworks can also use functionality spread across multiple components/libraries/systems, and making an UI kit thread-safe would likely require a lot of effort for dubious benefit (user input normally has to be processed strictly in order because clicking on a button and then pressing "enter" is different from pressing enter and then clicking on a button).
There are some specific scenarios where multiple threads are safe in a UI. For example, it's relatively common to be able to pass off an OpenGL context to another thread... so you can do OpenGL rendering in a thread separate from the main UI thread, if you like. Some UI frameworks specifically support this use case, e.g., certain methods on the OpenGL widgets are described as thread-safe. Individual OpenGL contexts are also not thread-safe and must be used from a single thread at a time (and they usually involve some thread-local context).
The typical way you make a responsive UI is by doing only UI work in the UI thread, and passing off all long-running computations to background threads.
> The problem is that many environments are effectively non-multi-threaded, especially the (usually single) thread/queue/process that draws the UI and responds to user input
Can you elaborate on why "especially" UI threads/queues/processes are "usually single"?