4 ms·
Loom is missing the point. Time has shown that bare threads are not a viable high-level API for managing concurrency. As it turns out, we humans don't think in
by Nullabillity 5y ago
Loom is missing the point.
Time has shown that bare threads are not a viable high-level API for managing concurrency. As it turns out, we humans don't think in terms of locks and condvars but "to do X, I first need to know Y". That maps perfectly onto futures(/promises). And once you have those, you don't need all the extra complexity and hacks that green threads (/"colourless async") bring in.
I'd take a system that combined the API of futures with the performance of OS threads over the opposite combination, any day of the week. But as it turns out, we don't have to choose. We can have the performance of futures with the API of futures.
Or we can waste person-years chasing mirages, I guess. I just hope I won't get stuck having to use the end product of this.
- rvcdbn 5y agoMaybe threads don’t work for your thinking style but your claim that this is generally true is baseless and pretty well refuted by languages like Go or Erlang that feature stackfull threads/processes as a critical part of their best-in-class concurrency stories.
- Nullabillity 5y agoErlang sidesteps the problem by avoiding mutable shared state, in this context they're threads/processes in name only. Go is just yet another implementation of green threads that is slightly less broken than prior implementations, because it had the benefit of being implemented on day 1 (so the whole ecosystem is green thread-aware). It's certainly nowhere near "best-in-class".
- chrisseaton 5y ago> Erlang sidesteps the problem by avoiding mutable shared state Erlang is maximal shared mutable state! Processes are mutable state and they’re shared between other processes.
- toast0 5y agoShared mutable state is hard to work with, but Java threads and Java promises both give you access to it. In either case, you'd need discipline to avoid patterns which reduce concurrency. From the article, it seems that Loom (in preview) enables the threaded model for Java to scale. IMHO, this is great because you can write simple straightforward code in a threaded model. You can certainly write complex code in a threaded model too. Maybe there's an argument that promises can be simple and straightforward too, but my experience with them hasn't been very straightforward.
- groestl 5y agoIf I look at a thread, I see futures all over the place. They're just implicit, and the OS takes care of concurrency/preemption. Sure, that means that you need concurrency primitives if you access shared resources, but only in the trivial case you can get away without shared state in the promise/future scenario as well (i.e. glue code that ties together the hard stuff). Downside is your code gets convoluted and your stacktraces suck.
- pron 5y agoI think you're mixing specific synchronisation/communication mechanisms with the basic concept of a thread, which is simply the sequential composition of instructions that is known and observable by the runtime. If you like the future/promise API, that will work even better with threads, because then the sequence is a reified concept known to the runtime and all its tools. You'll be able to step through the sequence of operations with a debugger; the profiler will know to associate operations with their context. What API you choose to compose your operations, whether you prefer message passing with no shared state, shared state with locks, or a combination of the two — that's all orthogonal to threads. All they are is a sequantial unit of instructions that may run concurrently to other such units, and is traceable and observable by the platform and its tools.
- Nullabillity 5y agoYou can implement futures by just running each future as a thread, but it doesn't really give you much. It's a lot more complex to write a preemptive thread scheduler + delegating future scheduler than to just write a future scheduler in the first place. Especially when that future scheduler already exists and works, and the preemptive one is a multi-year research project away.
- pron 5y agoIt gives you a lot (aside from the ability to use existing libraries and APIs): observability and debuggabillity. Supporting tooling has been one of the most important aspects of this project, because even those who were willing to write asynchronous code, and even the few who actually enjoyed it, constantly complained — and rightly so — that they cannot easily observe, debug and profile such programs. When it comes to "serious" applications, observability is one of the most important aspects and requirements of a system. Instead of introducing new kind of sequenatial code unit through all layers of tooling — which would have been a huge project anyway, we abstracted the existing thread concept.
- IshKebab 5y agoThreads have essentially the same API as Futures - normally you have some join of join handle and you can join a set of threads (the equivalent of awaiting a set of futures). Threads don't require locks and condvars. You can use channels and scoped joins etc. if you want. Give me some async code and I'll show you an easier threaded version.
- bpicolo 5y agoThe goroutine model in go is plenty conceptually simple for concurrency. Correct me if I'm wrong, but loom seems similar in that sense? I don't find myself missing out on futures in Go.