4 ms·
It's a different model. Microsoft did work on green threads a while ago and decided against continuing. Links: https://github.com/dotnet/runtimelab/issues/239
by peteri 2y ago
It's a different model. Microsoft did work on green threads a while ago and decided against continuing.
Links:
https://github.com/dotnet/runtimelab/issues/2398 https://github.com/dotnet/runtimelab/issues/2398
https://github.com/dotnet/runtimelab/blob/feature/green-threads/docs/design/features/greenthreads.md https://github.com/dotnet/runtimelab/blob/feature/green-thre...
- pjmlp 2y agoIt should be pointed out, that the main reason they didn't go further was because of added complexity in .NET, when async/await already exists. > Green threads introduce a completely new async programming model. The interaction between green threads and the existing async model is quite complex for .NET developers. For example, invoking async methods from green thread code requires a sync-over-async code pattern that is a very poor choice if the code is executed on a regular thread. Also to note that even the current model is complex enough to warrant a FAQ, https://devblogs.microsoft.com/dotnet/configureawait-faq https://devblogs.microsoft.com/dotnet/configureawait-faq https://github.com/davidfowl/AspNetCoreDiagnosticScenarios/blob/master/AsyncGuidance.md https://github.com/davidfowl/AspNetCoreDiagnosticScenarios/b...
- neonsunset 2y agoThis FAQ is a bit outdated in places, and is not something most users should worry about in practice. JVM Green Threads here serve predominantly back-end scenarios, where most of the items on the list are not of concern. This list also exists to address bad habits that carried over from before the tasks were introduced, many years ago. In general, the perceived want of green threads is in part caused by misunderstanding of that one bad article about function coloring. And that one bad article about function coloring also does not talk about the way you do async in C#. Async/await in C# in back-end is a very easy to work with model with explicit understanding where a method returns an operation that promises to complete in the future or not, and composing tasks[0] for easy (massive) concurrency is significantly more idiomatic than doing so with green threads or completable futures that existed in Java before these. And as evidenced by adoption of green threads by large scale Java projects, turns out the failure modes share similarities except green threads end up violating way more expectations and the code author may not have any indication or explicit mechanism to address this, like using AsyncLocal. Also one change to look for is "Runtime Handled Tasks" project in .NET that will replace Roslyn-generated state machine code with runtime-provided suspension mechanism which will only ever suspend at true suspension points where task's execution actually yields asynchronously. So far numbers show at least 5x decrease in overhead, which is massive and will bring performance of computation heavy async paths in line with sync ones: https://github.com/dotnet/runtimelab/blob/feature/async2-experiment/docs/design/features/runtime-handled-tasks.md#benchmark-of-minimum-call-cost-between-async-and-async2-functions https://github.com/dotnet/runtimelab/blob/feature/async2-exp... Note that you were trivially able to have millions of scheduled tasks even before that as they are very lightweight. [0]: e.g. sending requests in parallel is just this using var http = new HttpClient() { BaseAddress = new("https://news.ycombinator.com/news") }; var requests = Enumerable .Range(1, 4) .Select(n => $"?p={n}") .Select(http.GetStringAsync); var pages = await Task.WhenAll(requests);
- ffsm8 2y agoI don't think that this would be a good showcase for Virtual Threads. The "async" API for Java is CompletableFutures, right? thats been stable for something like 10 years, so no real change since Java 8. You'd jsut have to define a ThreadPool with n Threads before, where each request would've blocked one pending thread. Now it just keeps going. So your equivalent Java example should've been something like this, but again: the completeable futures api is pretty old at this point. @HttpExchange(value = "https://news.ycombinator.com") interface HnClient { @GetExchange("news?p={page}") CompletableFuture<String> getNews(@PathVariable("page") Integer page); } @RequiredArgsConstructor @Service class HnService { private final HnClient hnClient; List<String> getNews() { var requests = IntStream.rangeClosed(1, 4) .boxed().map(hnClient::getNews).toList(); return requests.stream().map(CompletableFuture::join).toList(); } }
- vips7L 2y agoStructured concurrency is still being developed: https://openjdk.org/jeps/453 https://openjdk.org/jeps/453 Also, I wouldnt consider that the equivalent Java code. That is all Spring and Lombok magic. Just write the code and just use java.net.HttpClient.
- ffsm8 2y ago> and just use java.net.HttpClient. No.
- no_wizard 2y agoit might be obvious to others, but why the 'No'?
- vips7L 2y agoThe standard http client doesn’t have as great of UX as other community libs. Most of us (including me) don’t like to use it. That being said, imo you can’t call something equivalent when doing a bunch of spring magic. This disregards that OPs logic isn’t equivalent at all. It waits for each future 1 by 1 instead of doing something like CompletableFuture.allOf or in JS: Promise.all.
- jayd16 2y agoIt would break a lot of the native interop and UI code devx of the language. Java was never as nice in those categories so it had less to lose going this path.