31 ms·
Virtual Threads Arrive in JDK 21, Ushering a New Era of Concurrency
- jononomo 3y agoIt seems that everyone is learning from Erlang and the BEAM!
- layer8 3y ago> However, due to the large number of virtual threads that can be created, developers should use thread-local variables with caution. What is the problem here? Just the per-virtual-thread memory consumption by the variable when it is used (which would be expected)?
- nicktelford 3y agoLock contention IIRC
- the-alchemist 3y agoYeah, poor performance and memory usage. In the Java world, thread locals are java.lang.ThreadLocal, basically a hashmap from thread to variable. Using a ThreadLocal is (usually) a code smell. It's optimized / supposed to be used with just a few threads, not millions.
- kaba0 3y agoFor what it worth, there actually is a separate JEP (I believe this: https://openjdk.org/jeps/429 https://openjdk.org/jeps/429 ) for a new, scope-bases solution that promises much better performance.
- deleted 3y ago[deleted]
- layer8 3y agoBut the lock would only need to be per platform thread?
- royjacobs 3y agoTypically ThreadLocals are used whenever something is costly to initialize per-request. The rule of thumb is usually: you might want to use some heavy object without locking, so you stick into a ThreadLocal. However, if suddenly you have a million threads then this optimization doesn't work anymore. Sure, the concept of ThreadLocal still works, but in practice you'll end up creating a million of these heavy objects - something you wanted to avoid!
- layer8 3y agoExpensive to initialize doesn’t imply large. And wanting to avoid expensive initialization (runtime) is orthogonal to wanting to avoid a larger memory footprint. So I don’t quite buy your argument.
- royjacobs 3y agoYour question was why the advice was given to avoid ThreadLocals. This is the primary reason. It's not necessarily related to avoiding a larger memory footprint.
- no_wizard 3y agoWhat will this mean for Kotlin and concurrency I wonder
- DeathArrow 3y agoHow are Java virtual threads compared to C# tasks? To me, they seem very similar.
- plumarr 3y agoThe main benefit of virtual threads it that they release their carrier thread when they call (non native) blocking code, so that other virtual threads can be executed by the same carrier. I don't think that it's the case for C# task, which also appear to be an higher level construct.
- Patrol8394 3y agoI really hope this is the end of complicated reactive frameworks! I love the old blocking spring controller paradigm, thread local and so on. It makes things much easier. Never liked webflux, so complicated and hard to debug. Simple things become a project! Virtual threads to the rescue!
- remon 3y agoI could not agree more. And that's coming from someone that converted to almost completely async/reactive/flux-y code. Reactive frameworks, almost by necessity, force developers to write less maintainable and readable code (objective fact, not an opinion). Lightweight threading is a significantly better approach to the same problem space.
- wiseowise 3y ago> objective fact, not an opinion Got any links where I can read about it?
- jmull 3y agoAre we dropping the "in" from "to usher in" now? Or is this just an incorrect headline?
- whoisthemachine 3y agoUsing virtual threads only, can one make a non-blocking UI application? Or do you still need to fall back to Promises or callbacks?
- bberrry 3y agoI'm not positive about this but I believe the virtual threads can yield at syscalls (i.e. IO calls). I don't think GUI application code is littered with these syscalls where a virtual thread can naturally yield so you get non-blocking for "free". Someone please correct me if I'm mistaken.
- jsmith45 3y agoUnder .NET's async await model, switching also generally only occurs when blocking IO is initiated (or blocking on a timer, etc). You cf course add your own yield points, but it is not frequently necessary. That is mostly limited to CPU/memory bound operations, as any IO bound operations would have the potential to yield. However, something important to remember is that UI frameworks generally require most or all UI interaction to occur on one logical thread. This is because making all the UI code safe for calling from multiple threads would require tons of work, and likely require one massive lock that serializes most ui compontent method calls, or tons of smaller locks. And that is just for the minimum of safety. UI work has tons of implicit state. User level logic would also likely need additional locking, since even if each method call to a control is thread safe, if you want to perform some kind of conditional action that does not already have some dedicated method, that would pose a problem without some form of synchronization code. One advantage of the async-await approach in UI scenarios (where continuations always get run on the UI Thread) is that you know that between two awaits, no other code will be running on the UI thread, so can avoid synchronization code. You know if you read a value from a control and then conditional call a method on it, you don't need to worry about racing with another thread. Now whenever an "await" occurs, potentially arbitrary other UI code may have run in the interim, so you may need to reverify the state of things. But this is still much simpler to handle than possibly being preempted at any time, or having another thread literally changing things in parallel. Green thread based approaches like Virtual Threads do avoid much of the complexity of async-await, but they often do lose those sorts of advantages. Even if the green thread approach has guarantees about the yield points (e.g. only has cooperative yields which only occur when certain specific methods are called), you still lose the ability to locally reason about where those yield points may occur, since any function/method call could potentially call one of those yielding functions, or call something that calls one of them, etc. The only way to regain that info is to "color" the functions again, which was the whole thing peple are trying to avoid with green threads in the first place.
- sys_64738 3y agoWhat are these things? It sounds like it is a time-sliced sharing that offers only concurrency and not parallelism. In other words, it's a userland construct and not a kernel thread. Sounds more like GO coroutines but do we really need another name for them?
- za3faran 3y agoAlready responded to here https://news.ycombinator.com/item?id=35537890 https://news.ycombinator.com/item?id=35537890
- beautybabe5 3y ago[dead]
- magicpeach9 3y ago[dead]
- oreomagie1 3y ago[dead]
- jobrofan3 3y ago[dead]
- pandaheart5 3y ago[dead]
- supergiggles9 3y ago[dead]
- pineapple76 3y ago[dead]
- rosecatcher09 3y ago[dead]
- starshadow7 3y ago[dead]
- moonkiller1 3y ago[dead]
- smile6745 3y ago[dead]
- dancingdimples1 3y ago[dead]
- menkiller 3y ago[dead]
- silenteyes12 3y ago[dead]
- dearangel5 3y ago[dead]
- overKill232 3y ago[dead]
- xoom2342 3y ago[dead]
- vkaku 3y agoThe issue I see is some companies' reluctance to even shift from Java 8 or move away from legacy. I guess that will be the biggest impediment to adoption of new features.
- pantulis 3y agoAre these green threads? -- edit myself: no, it can't be. JVM had green threads since eons ago, according to wikipedia. -- edit again: this SO thread --pun intended!-- explains it https://stackoverflow.com/questions/74639116/what-is-the-difference-between-green-threads-and-virtual-threads https://stackoverflow.com/questions/74639116/what-is-the-dif...
- HippoBaro 3y agoYes, these are user land threads. Sometimes they are also called fibers, green threads, virtual threads, or stackfull coroutines.
- deleted 3y ago[deleted]
- deleted 3y ago[deleted]
- Valodim 3y agoThat's pretty confusing without some more context, yeah. Not the best article in this regard. > In fact, in very early Java versions, the JVM threads were multiplexed onto OS threads (also known as platform threads), in what were referred to as green threads because those earliest JVM implementations actually used only a single platform thread. > However, this single platform thread practice died away around the Java 1.2 and Java 1.3 era (and slightly earlier on Sun’s Solaris OS). Modern Java versions running on mainstream OSs instead implement the rule that one Java thread equals exactly one OS thread. https://blogs.oracle.com/javamagazine/post/going-inside-javas-project-loom-and-virtual-threads https://blogs.oracle.com/javamagazine/post/going-inside-java...
- flockonus 3y agoI found the StackOverflow accepted answer to be a very clear explanation, it summarizes and re-iterates what matters: "With Virtual Threads, multiple virtual threads can run on multiple native threads (n:m mapping)"
- 3y ago
- namdnay 3y agohopefully this will mean the end of Reactor Core and all that craziness
- MrBuddyCasino 3y agoI'll drink to that.
- noelwelsh 3y agoNext stop, tail calls plz.
- JonChesterfield 3y agoTail calls make stack traces harder to read and it looks from the outside like java development is primarily about reading stack traces
- aembleton 3y agoThe strange thing is that the JVM can handle them because Scala and Kotlin have them. Java though, doesn't.
- aardvark179 3y agoScala and Kotlin just implement them using a trampoline, the JVM does not itself support tail calls.
- aembleton 3y agoHow do they do that? I thought it would need to be done at the JVM level so that stack didn't grow.
- kaba0 3y agoEvery recursion can be converted to code that uses only a single stack. Tail calls can be easily eliminated at compile time automatically as well, that’s why it only needs compile-time support — I don’t specifically know what Scala/etc do, but the mentioned trampoline is basically just a function pointer one can jump to, accumulating results in some non-stack data structure if needed.
- TheDong 3y agoSo with this, the last thing Go had going for it over Java is gone, right? Java has an obviously better type system, while Java originated the billion dollar mistake, Java also at this point has much better practices around handling nulls than Go, Java's jars are more portable than go's binaries, Java's GC performs better, Java has a more mature ecosystem and more libraries... Java has better IDE support and comparable compile times. I guess at this point the only major difference is that you can teach a 3 year old to write Go more easily, so ChatGPT produces correct Go more easily than Java, and the dependency management story differs a little (though I don't think you can really call a winner or loser on that one, it's just different)
- the-alchemist 3y agoThe "original billion dollar mistake" is lack of runtime bounds checking (in the creator's words), not the idea of a null/nil/undefined generally.
- lightbendover 3y ago> the billion dollar mistake Eh, a billion dollars isn't too bad.
- Mawr 3y agoThis is missing the forest for the trees. Languages are very complex, you will not get a good picture of their overall strengths and weaknesses if you limit yourself to a very zoomed-in view, like comparing a few features of the languages themselves. As an example, consider the digital camera market vs the cameras in smartphones. The digital camera is a clear winner! So many features. The quality of photos taken is objectively better in every metric too. And yet the digital camera market is dying, completely killed by smartphones. But why, the features are cleary better right?! Because we're looking at it wrong, we're tunnel-visioned on the "camera" part. We need to look at what actually matters. Thankfully, that's simple to answer and is the same for every product in existence. All that matters is the user experience. Nobody wants extra features on their camera, nobody wants a camera in the first place, nobody wants to take photos either. What people actually want is to preserve the moment of their first born child taking their first steps. The technology is irrelevant as long as it lets the user do what they really want. Why would I want a digital camera when my smartphone has a decent enough one that is effectively free and always available? A low quality camera on you is infinitely more valuable than the professional camera at home. Programming languages are no different, just that "users" in this case are programmers, which seems to be confusing to some. What is the developer experience of using Java vs Go? - that's the real question you need to answer to get to the bottom of this. Start a new project and write some code in both languages, compare the experiences. Be wary of biases, if you have pre-existing experience in one of the languages it's going to shadow your judgement (the curse of knowledge). Pay attention to aspects of good design - how many pointless decisions do you have to get through before actually shipping code? Go eliminates whole areas of pain points: - Dependency management? Go modules. - Tests? Built-in. - Code formatting? Built-in autoformatter. - Compilation time? As fast as it gets. - Distribution? Single binary. - Writing code? Minimal ceremony, just make a function. - Performance? The idiomatic code you write will naturally perform well due to value types, explicit pointers, a culture of straightforward code with no needless indirection. If you need to optimize, the profiling tooling is great and the optimizations themselves straightforward due to intuitive language and GC semantics - just reduce allocations. - GC? A single implementation, good enough for 99% of cases. Two whole knobs available if you really need to tune it. Performs well due to the language not getting in its way. - Standard library? Excellent, good balance between batteries-included and bloat. The built-in HTTP server is suitable for 80%+ of workloads. - Concurrency? Core to the language - syntactically supported green threads. The entire language and its ecosystem are built with it in mind. - Linting? Community-made linter runner with a curated list of good linters. - Found a bug in a library? No problem, the library is written in straightforward Go, the same flavor of Go you've been writing. It's of course autoformatted as well. There you go, a single go-to solution to each problem. The language's designers have gotten all the pointless details out of the way for you. You get to focus on writing code. Now compare the above points with Java. Go was designed for developers, with the same philosophy Steve Jobs designed Apple products for users. Java wasn't. Simple as.
- seanparsons 3y agoWell it's not really ushering it in, given that this is what Haskell has had for a decade at least.
- marginalia_nu 3y agoWell, yeah. Haskell is a research language, while Java's stated design philosophy from day one has been to be conservative with adding new features, and judiciously add new features after they've proven useful in other languages.
- maxbond 3y agoTo be fair though M:N threads aren't the provenance of research language, Go and Rust both have them, and I'm sure some other languages. (But it's awesome Java has them now too, other languages getting the feature earlier doesn't really devalue it.)
- kaba0 3y agoRust doesn’t have them, though.
- maxbond 3y agoIn what way? async-std and tokio both support M:N.
- kaba0 3y agoBut they can’t turn blocking calls to non-blocking which is the whole point, that requires runtime support.
- maxbond 3y agoOh interesting, that's very cool, I didn't realize Java was doing that. That's a different axis than M:N though (cooperative versus preemptive) and you could definitely write a preemptive async runtime for Rust (rtic comes to mind). But the async-std and tokio runtimes are certainly cooperative. (As a note, cooperative scheduling also requires a runtime - Rust might not "have a runtime" by default but you need to opt into one to use async.)
- invalidname 3y agoIf you need a video explanation of virtual threads this might help: https://www.youtube.com/watch?v=4mf24mzm0ks https://www.youtube.com/watch?v=4mf24mzm0ks
- spuz 3y agoThanks - that's really helpful.
- ranguna 3y agoAre these like javascript promises or goroutines?
- MathMonkeyMan 3y agoMore like goroutines. They remind me of Guile's fibers: https://github.com/wingo/fibers https://github.com/wingo/fibers
- avodonosov 3y agoIn javascript the analogue is async / await, only without the need to manually mark code "async"
- Rapzid 3y agoIf you want to return a future you'll need to note that in the return type.
- kaba0 3y agoBut that arguably doesn’t use this feature to its fullest — the most naive/easy to comprehend way to do concurrency is to start up multiple threads calculating something and simply wait for all of them to return, and at this point you are free to use the calculated results as is. This is the most-idiomatic way to make java virtual threads (with a try-with-resources block)
- Rapzid 3y agoI'm not sure I understand. The waiting for them all to return; isn't that Callable<T>? Goroutines can wrap code you don't want to block callers, but in practice that get hidden behind APIs that return channels.
- avodonosov 3y agoIt's not about feature / promise return types. Consider: int someFunc() { doA(); doB(); byte data[] = readFromSocket(); return doC(data); } int callerFunc() { doX(); System.out.println(someFunc()); doY(); } when we invoke the callerFunc() in a virtual thread, it executes till the potentially blocking socket reading, creates a callback or future -like object containing doC(), System.out.println(), doY() - such object is called a "continuation", see "continuation passing style". Then the socket reading is iniitated in an async way, with continuation registered as a callback to be invoked upon completion. Then the native OS thread is freed to do any other work. In javascript approach we would need to manually mark some places `async` and use `await`. @async int someFunc() { doA(); doB(); byte[] data = await readFromSocket(); return doC(data); } @async int callerFunc() { doX(); System.out.println(await someFunc()); doY(); } So async / await is a poor man's continuation passing style. The need to differentiate between 'async' and non 'async' code makes it more difficult to refactor or mix code between 'async' and non 'async' domains. Some people argue that it's better to have the explicit distinction. I personally don't see benefits of this.
- Barrin92 3y agoI haven't touched Java since school and never worked in it professionally and that's been well over a decade. Is there a resource that people recommend that gives a good introduction to modern Java? Preferably succinct but doesn't need to be.
- ulimn 3y agoI think the book "Core Java for the Impatient" by Cay S. Horstmann is a really good one on (relatively) new java. The author has a 2 volume, longer book as well if you want more details.
- xdavidliu 3y agoThe Horstmann 2-volume series is probably the best books for someone learning Java, period. I wished there was a book like this for other languages: both comprehensive and up-to-date. For C++, I guess the closest would be Stroustrup, but even as the creator of the language, Stroustrup's books just aren't as comfortable to read as Horstmann's.
- moring 3y agoThe top comment in this thread [1] highlights (potential) problems with virtual threads, referring to this PDF [2]. Does anyone know if these actually manifest in the way they are implemented? [1] https://www.reddit.com/r/rust/comments/xrrjec/virtual_threads_in_rust/ https://www.reddit.com/r/rust/comments/xrrjec/virtual_thread... [2] https://www.open-std.org/JTC1/SC22/WG21/docs/papers/2018/p1364r0.pdf https://www.open-std.org/JTC1/SC22/WG21/docs/papers/2018/p13...
- ddorian43 3y agoMaybe ask in /r/java, the main developer is there (pron98).
- kaba0 3y agoHe might just pop up here, he is a frequent HNer with username pron.
- dfox 3y agoThis is relevant to environments where the user code is statically compiled into native code that depends on some thin runtime library and more or less directly interacts with C code. In case of full blown VM many of these problems are not as significant as the internal thread state representation is non-native anyway and you can dynamically instrument pretty much whatever you want (one issue are system calls and system library functions that do not have non-blocking equivalent, but that could be handled by either having separate OS-level thread for such things or simply ignoring the issue, with real implementations doing some mix of these two approaches).
- BenoitP 3y agoYour second link is from 2018, and would indeed need a case study for Loom. For example the concerns about thread-local storage are addressed, and the base overhead is understood (as in: don't use them for CPU-bound worloads, they'll fare better on IO-bound workloads) Also, the cases studies in that paper are platform-level when I believe the language has to be involved; as a runtime has more information when resuming to a suspension point. The paper even acknowledges Go as a successful implementation although with C-compatibility call overhead caveat. In the Java world, the vast majority of programs stay in the Java language. So I'd say that paper would list Loom as the best implementation (And maybe revise their recommendation. It'd be useful to have that author's opinion of Loom in 2023)
- piokoch 3y agoWhile this is definitely a good new, we need to be very careful. Why? Those new fancy threads are stored on heap and need to be garbage collected. If you buy into ads and believe that you can create for free millions of threads, then, well, it is not gonna work on production. Because of this server based on new threads does not need to be more performant, Jetty server guys tested this and they were not that happy: https://webtide.com/do-looms-claims-stack-up-part-1/ https://webtide.com/do-looms-claims-stack-up-part-1/ Before getting too excited I advise to watch Tomasz Nurkiewicz lecture on the subject - https://www.youtube.com/watch?v=n_XRUljffu0 https://www.youtube.com/watch?v=n_XRUljffu0, it explains what are the trade-offs here. No silver bullet, again.
- pron 3y ago1. Platform threads place a heavier burden on the GC. It's true that virtual threads are allocated on the heap, but platform threads are GC roots, which is worse. The GC easily deals with a gazillion heap objects; it's rather unhappy with lots of roots. The number of heap objects that virtual threads occupy is roughly the same as the number of heap objects that async code allocates anyway. 2. The Jetty experiment measured the wrong thing as they misunderstood the origin of the "million thread" scenario. What happens in a real application is that you have some number of threads with deep stacks servicing incoming requests -- say 50K concurrent sessions -- and then each of those fans out to, say, 19 micro services in parallel, each of those outgoing requests is done on a virtual thread with a very small stack, and that's how you get to 1M threads. I.e. when you have a high number of threads, only a small minority of them (5% in this example) have a deep stack. 3. I don't think anyone would claim anything is a silver bullet. All virtual threads do is let a server service the same throughput as asynchronous code does, but the code is much simpler and it is observable, i.e. easily debuggable and profitable, something that async code can't do.
- MarkSweep 3y agoRegarding #1, would not the stacks of the lightweight threads have to root have to root any object on it? Otherwise the GC would free objects out from under the virtual thread, right? I could imagine that by having fewer physical threads running, the stop-the-world part of garbage collection could suspend the runtime more quickly. That could reduce the effect of GC-pauses.
- kjto 3y ago> Virtual threads offer a more efficient alternative to platform threads, allowing developers to handle a large number of tasks with significantly lower overhead. they should have just called them "Tasks" leaving the already overloaded term "virtual" out of the conversation.
- layer8 3y agoThey are of type `Thread`, for interoperability with existing code.
- marginalia_nu 3y agoJava's already got tasks[1] within the namespace of parallelism though, but it hasn't overloaded any meaning onto virtual. [1] https://docs.oracle.com/javase/9/docs/api/index.html?javafx/concurrent/Task.html https://docs.oracle.com/javase/9/docs/api/index.html?javafx/...
- vips7L 3y agoJavaFX is not really a part of Java and isn’t actually shipped with most builds of OpenJdk. Azul Zulu is the only build that I know of that you can get FX built in.
- BenoitP 3y agoIMHO virtual is the perfect word. The JVM's entire schtick is abstracting (virtual) hardware (machine). A simple API pertaining to intent, that can be materialized depending on OS and hardware. Calls are virtual, though under the hood the compiler may inline them. Memory is managed, though through analysis some allocations will go on the stack. Threads are now (no full grandfathering, but they tried) virtual, and the runtime may now optimize them differently on different OSes and hardware.
- surfsvammel 3y agoEvery time something show up about anything related to Java, the discussions turn to this flame war about what language are better or worse than Java. Why can’t we just discuss the article at hand? In this case, I’d love to hear more from experienced Java developers, with existing code-bases, who have tested these new virtual threads out.
- re-thc 3y agoA lot of work still needs to be done on the libraries and other tools before it's useful for end users. We've spent years migrating to "reactive frameworks" or being stuck in "legacy". Virtual threads isn't just something to "enable". You do need to adapt existing codebases somewhat e.g. use of synchronization. The upcoming future is likely a mix of reactive and virtual threads where appropriate. Virtual threads is still very good for short lived tasks.
- surfsvammel 3y agoThe application that we are working on uses thousands of platform threads today (split over a handful of applicationservers). It’s a humongous banking system. I have been working on performance related improvements for years. I am now curious if these new virtual threads might be beneficial for us in some places. Need to read up on them a bit more
- flippinburgers 3y agoThe top level comment is someone gushing over Java so perhaps Java advocates bring this on themselves?
- gpderetta 3y agoIndeed. It is the curse of the Stroustrup law.
- alkonaut 3y agoHow is a system of virtual threads different from typical "a pool of tasks and a pool of threads to perform them on" systems like e.g. the .NET TPL?
- jillesvangurp 3y agoConceptually, these are all variations of the same thing. The difference is in how you use them and how much boiler plate you need to use them. Funnily enough, the first versions of Java did not support OS threads and only had green threads for a while. Supporting real threads was a big deal at the time as it allowed you to use more than 1 processor. Of course, processors were single core at the time and most computers only had one of those anyway. Java 1.1 laid the foundations for proper multi threading and green thread support was eventually removed with Java 1.3. With Java 1.5 we got the java.concurrent package which enabled doing more complicated things with locks and other synchronization primitives that were a bit less primitive & brittle than using the synchronized & volatile keywords. That includes implementing green threads on top of real threads. Which is what frameworks like vert.x and others have been doing for ages. So, in a way we're coming full circle here with virtual threads re-using the thread API, which in turn reused the original green thread APIs in Java 1.0.
- kaba0 3y agoThat leaves off basically the whole point of it: JVM-native blocking calls don’t have to actually block, they can do an OS-native async call, and do some other work on the thread, returning upon completion. Since Java uses very little FFI, it will benefit greatly from this automagical “no more blockingness”, of course only when there is some other available work in the meanwhile. Servers are the best fit for that.
- killerstorm 3y agoI guess the idea is that you don't have to write tasks explicitly - if you have a sequence of actions you can just write it as a regular code, and the runtime will automatically insert points where your code might be suspended waiting for IO or other threads.
- neonsunset 3y agoNew Era of concurrency? It began in arguably better languages a decade ago.
- philonoist 3y agoAnyone familiar with Java and Kotlin, please expand on how close is Java in feature parity with Kotlin?
- BenoitP 3y agoKotlin's are stackless (as in emulated by the compiler), Java's are stackful (as in a chunk of stack is copied into the heap along with a program resume point) This means Kotlin's functions can become colored [1] which is a problem. This said, I'm fully expecting Kotlin to react and pass on this feature to the users. Maybe after figuring out how to deal with Android. [1] https://journal.stuffwithstuff.com/2015/02/01/what-color-is-your-function/ https://journal.stuffwithstuff.com/2015/02/01/what-color-is-...
- cutler 3y ago`Executors.newVirtualThreadPerTaskExecutor()`. Java verbosity is alive and well.
- wiseowise 3y agoHow would you call it?
- kaba0 3y agoYeah, some C-style would be so preferred: e_nvtpte() /s
- mahmoudimus 3y agoYeah that part is not great. OTOH, I know exactly what it does :)
- thom 3y agoAny other naming here would be worse.
- deleted 3y ago[deleted]
- i386 3y agoGod forbid we have names that explain the subject
- lenkite 3y agoSo is Apple/Swift, but Apple always gets a smile instead of a smirk here on HN. func CMMetadataFormatDescriptionCreateWithMetadataFormatDescriptionAndMetadataSpecifications( allocator: CFAllocator?, sourceDescription: CMMetadataFormatDescription, metadataSpecifications: CFArray, formatDescriptionOut: UnsafeMutablePointer<CMMetadataFormatDescription?> ) -> OSStatus
- cutler 3y agoWow. Where did you find that specimen?
- andix 3y agoIs this the equivalent for the .NET TPL (task parallel library), which exists for over a decade now?
- francasso 3y agoNot familiar with .NET, virtual threads in Java are an alternative to async await in other languages. The approach Java took is similar to green threads in go.
- andix 3y agoTPL is a library to create Tasks and run them. They can be scheduled in different ways, on (native) thread pools for example. They are commonly used together with async/await. They are very similar to promises in JavaScript. I read about the approach without async/await, but honestly I don’t really get it. Seems to be very dangerous to me, if you give up control about scheduling. But sure, async/await is completely viral and it is everywhere now. Most functions tend to be async.
- ahtihn 3y ago> virtual threads in Java are an alternative to async await in other languages Not really. Async/Await is mostly about syntax. Transform callback-hell into something that looks like linear code. The underlying threading model doesn't really matter for that.
- bullen 3y agoNIO solved the problems with threads on the network in Java 1.5 (seminal cornerstone API that also had the concurrency package and rewrote the entire JVM memory model), but only in 1.7 the epoll solution became stable. 2004 -> 2011, 7 years! Now they hopefully can work around the kernel for file descriptors (network and disk) saving 30% CPU globally on all Java servers. Many nuclear power plants wasted on the kernel.
- nicktelford 3y ago> Now they hopefully can work around the kernel for file descriptors (network and disk) saving 30% CPU globally on all Java servers. Can you expand on this a little? Are you referring to the necessity to copy between kernel memory and user-space memory, or something else?
- wolf550e 3y ago> Now they hopefully can work around the kernel for file descriptors (network and disk) saving 30% CPU globally on all Java servers. How does this work around the kernel? This lets you write java code that uses async IO but make it look nice, like golang code. But this isn't DPDK.
- bullen 3y agoThe JDK would have access to network card and SSD directly. Bypassing the kernel. Java is already sandboxed we don't need the kernel unless the net/ssd drivers crash completely. It's a huge task/risk, but 30% is alot.
- 3y ago
- kosolam 3y agoThe biggest win by far IMHO is a performant alternative for io intensive applications for async frameworks. Not using an async framework tremendously simplifies your code. Code complexity has an enormous projection on everything else, especially when talking on the business level. First and foremost the cost of development and time to market rises. And then comes the cost of maintenance.
- jononomo 3y agoIf you want to use an async framework without sacrificing simplicity, look into Elixir/Erlang and the BEAM.
- jayd16 3y agoIf you want to run concurrent io requests, don't you still need to use an async framework and all the fork/join logic? I suppose the slow and naive way is now easier to let limp along as you won't run out of threads?
- throwaway2847 3y agoWhy would you need an async framework? All blocking I/O in the Java runtime has been changed to yield in a virtual thread.
- jayd16 3y agoThey added the structured concurrency package because you still need some kind of async framework for concurrency. Maybe the confusion is just the term "framework" as opposed to API? I don't mean a third party library is needed. The built in JDK alone is sufficient but you're still juggling promises/futures and the like.
- kaba0 3y agoYou don’t really need anything, they just make forking and subsequent joining+exception handling easier. You can just use the decades old thread api over virtual threads as is if you wish, but this “structured concurrency” concept, similar to goto vs structured control flow will make it much more productive and easier to reason about.
- theandrewbailey 3y ago> Platform threads are a one-to-one wrapper over operating system threads, while virtual threads are lightweight implementations provided by the JDK that can run many virtual threads on the same OS thread. Virtual threads offer a more efficient alternative to platform threads, allowing developers to handle a large number of tasks with significantly lower overhead. > The JDK can now run up to 10,000 concurrent virtual threads on a small number of operating system (OS) threads, as little as one OK, but why bother with virtual threads if the JVM could just magically decide to run all my virtual threads on one thread? I guess "efficient" in this context doesn't mean "fast". I want my code to run on all available cores, and not be hobbled by a JVM that decided to hate me today.
- mschaef 3y ago> OK, but why bother with virtual threads if the JVM could just magically decide to run all my virtual threads on one thread? I guess "efficient" in this context doesn't mean "fast". I want my code to run on all available cores, and not be hobbled by a JVM that decided to hate me today. If you have 10,000 threads blocked on a sleep (or I/O), then there's no reason to run them on more than one code. In fact, they won't usually be running at all. This is the use case. It's less about giving the VM a new way to 'hate you today', and more about telling the VM when it can save resources and share system threads. Edit: There is some potential for unexpected downside to the extent that this introduces a new scheduler for the virtual threads. If every thread is an OS thread, then it's the OS scheduler that controls when they run. With virtual threads, I assume the scheduling policy (deciding when virtual threads get time on OS threads) is controlled by a JVM scheduler that may or may not be as good at making the choices you'd like. But probably best to assume it won't summarily drop everything on a single OS thread and call it a day.