Live data from Hacker News

Java Virtual Threads Preview

openjdk.java.net

241–250 of 270 posts

Re: Java Virtual Threads Preview

#241

Earlier quoted context omitted.

> ~~it's~~ Why are you calling that out? The original "its" was correct without the apostrophe.

Twisol was right - I was trying to imply strikethrough using the Markdown syntax in an attempt to depict the idea of replacing "its" with "Java's". It didn't work as well as I hoped. In my mind I can see more 'Awk' scribbles on my post, and looking at it I agree :) Adding in the 's is 100% my mistake. I've been guilty of using "it's" as the possessive form for most of my life, but that changes today! :)

> but that changes today! :)

Exciting! :)

Re: Java Virtual Threads Preview

#242

Earlier quoted context omitted.

https://quarkus.io/guides/building-native-image You should try Quarkus. It is a production framework built by Redhat. It uses Java-GraalVM under the cover to compile your entire webapp to an executable (like golang does). It's just as fast. Java is the highest performance and most tuned VM there is. I think you're really thinking of java from a long time ago, if ur thinking this

> Java is the highest performance and most tuned VM there is. Not defending the opposite argument, but V8 is also pretty impressive. It's rooted in work done for Smalltalk long before JavaScript was a thing.

> It's rooted in work done for Smalltalk long before JavaScript was a thing.

The same is true of HotSpot. https://en.wikipedia.org/wiki/HotSpot_(virtual_machine)#Hist...

Re: Java Virtual Threads Preview

#243
post #208
post #119

Earlier quoted context omitted.

Eclipse and NetBeans do exist, and... ehhhhh. I used NetBeans for a long time; couldn't stand Eclipse; and these days I only use IntelliJ. But the others absolutely exist, and it'd be hard to say that Apache and the Eclipse Foundation aren't deeply embedded in the Java ecosystem.

Eclipse is fine. Especially from VsCode where it uses the Eclipse language server. It boots fast, and when you run it with a modern JVM and GC the memory usage is leagues lower than IntelliJ.

> Especially from VsCode where it uses the Eclipse language server.

Sure, but my particular complaint isn't with the functionality; it's with the UI. Yes, VS Code absolutely improves the experience.

Re: Java Virtual Threads Preview

#244
post #164

Earlier quoted context omitted.

> You know, the kind of code where you have to communicate with some outside device and it is easy to do blockingly but devolves to state machine madness if you need to do other things concurrently. Speaking personally, I've found Lua's coroutines to have the nicest experience for modeling flows like that. The big issue with async/await is the function color problem [0] -- writing async functions is perfectly fine, b…

I used to struggle with "function color" until I realized that the functions just have a different type. Async functions return a future `Task `, while normal function return a plain `Thing`. Of course they are incompatible. A different way of looking at it is that in asyncs functions you should only do things that have negligible runtime (compared to the response time of your GUI or network service). If your task ne…

I also think of "color" fundamentally as different types; it's just painful to have two kinds of functions that you can't combine. I, personally, really feel that async/await is just adding a second kind of continuation (promises/futures) to a language that already has a perfectly good one (call stacks), and the language ergonomics suffers for it.

The reason I say functional languages don't get bit by this as bad is because functional languages rely far less on the specific notion of a call stack, and it's usually much easier to work with continuations (either via primitives like shift/reset or via syntax like do-notation).

Re: Java Virtual Threads Preview

#245
post #235
post #45

Earlier quoted context omitted.

I'd love to know who, of those pinned to an LTS release, has actually made use of a support contract with a company providing contracted support for an LTS release, whether it's Oracle or another company. I don't doubt they exist, but I have no idea what that support even looks like. My team has been happily tracking the twice-yearly JDK bumps. We started development three years ago against Java 8 and made a series o…

I never found use for the visitor pattern in Java anyway. Isn't that defeated by instanceof?

Traditional wisdom says that you shouldn't use `instanceof`, because downcasting is bad and you should work with an interface uniformly implemented by any particular subclass. The Visitor pattern accomplishes this by giving the shared supertype a `match` method accepting, effectively, a bunch of callbacks, and each subclass just chooses which callback to invoke.

In algebraic type notation, this pattern replaces a function returning a sum type, X -> A + B + C, with a function accepting a callback that accepts a sum type, `X -> (A + B + C -> Y) -> Y`. But function accepting a sum type is the same as a product of functions, so you have `X -> (A -> Y, B -> Y, C -> Y) -> Y`. The product of functions is the visitor, and `X` is the thing you're visiting.

Traditional wisdom is correct when you have an open family of subclasses (i.e. you don't know, and shouldn't know, precisely how many subclasses there are). But for a closed family, it's just unnecessary; you're blinding yourself from information you already possessed.

Re: Java Virtual Threads Preview

#246
post #153

Earlier quoted context omitted.

They are not fully preemptively scheduled though right? If I have a virtual thread that enters an infinite loop it will not be possible to reclaim its host OS thread no?

That's a good question. It's not very easy to do that with regular Java threads either, though [0], and I think everybody considers those "fully preemptively scheduled". Preemptive scheduling is more about whether the scheduler (in this case, the OS scheduling the carrier threads) can pause a thread no matter where it is in its processing, and since virtual threads are executed by OS threads (the virtual part is just…

Hmm, not sure I agree. In the case of OS threads, the kernel will preempt a misbehaving thread and give the CPU to another thread according to priority. In the case where a virtual thread enters an infinite loop however there is no way for the virtual thread scheduler to do the same, unless kernel interruptions of the stuck host OS thread somehow return control to the virtual thread scheduler instead of whatever code was executing when the host thread was preempted. It's not clear to me this is really feasible though.

Re: Java Virtual Threads Preview

#247
post #216
post #32

Earlier quoted context omitted.

Tildes are used for strikethrough in some markup dialects (including mark down ), so I think they meant to depict replacing "its" with "Java's". No clue on the apostrophe.

(Forgive my grammar nazism.) The possessive form of "it" is "its": "The dog wagged its tail". But for basically everything other than pronouns and plurals, the possessive form involves adding "apostrophe s". In recent years, many people have tried to apply this rule to "it". But the problem is that "it's" is understood to be a contraction of "it is" or "it has"; furthermore, "its" already exists as the standard posse…

> One thing I say to people using "it's" is that by analogy, you also need to say: "He got he's skills. She missed she's ride. They have they's meeting."

This is a great distillation of the intuition I've always had, but never quite verbalized.

Re: Java Virtual Threads Preview

#248
post #153

Earlier quoted context omitted.

That's a good question. It's not very easy to do that with regular Java threads either, though [0], and I think everybody considers those "fully preemptively scheduled". Preemptive scheduling is more about whether the scheduler (in this case, the OS scheduling the carrier threads) can pause a thread no matter where it is in its processing, and since virtual threads are executed by OS threads (the virtual part is just…

Hmm, not sure I agree. In the case of OS threads, the kernel will preempt a misbehaving thread and give the CPU to another thread according to priority. In the case where a virtual thread enters an infinite loop however there is no way for the virtual thread scheduler to do the same, unless kernel interruptions of the stuck host OS thread somehow return control to the virtual thread scheduler instead of whatever code…

Yes, it's definitely possible that a spinning virtual thread will effectively pin the current OS thread. The Loom folks could keep, say, a count of how many instructions the virtual thread has executed, and pre-empt it itself if it needs to. This could fight a little with the OS scheduler, so I'm not sure what the tradeoffs are, but if you absolutely cannot allow a spinning virtual thread to effectively pin an OS thread, you'd want to do this.

If you're going to do a bunch of computation without blocking, I'm not sure virtual threads are the tool you want to apply in the first place. They're meant to provide cheap blocking and cheap context switching. If you've got a job that's more CPU-bound than I/O bound, it's probably worth using OS threads instead.

Re: Java Virtual Threads Preview

#249

There is a spectrum of solutions for dealing with slow I/O in programming languages (well, all I/O is best assumed to be slow I/O). At the two ends of the spectrum are: - continuation-passing style (CPS), hand-coded or compiler - preemptive threading / processes In between lie various solutions, like async/await (closer to CPS), and green threads (closer to preemptive threading). The key difference between the two en…

This is partially right. But the Java implementation under the hood is still a CPS transformation, so it only allocates the memory that is required for the "virtual stack". Compared to that Go - which has similar semantics - allocates a more classical stack for each goroutine, which can however grow over time. The CPS approach is certainly more space efficient, but but I'm not sure how much of a difference it really…

Normally a POSIX thread gets a very large stack (1MB is typically the default), and obviously these "virtual stacks" will only be as large as they grow (splayed on the heap?). But the memory for those POSIX thread stacks isn't necessarily allocated up front! The OS grows the thread when the thread traps trying to access the guard page, so it's not really a 1MB stack.

Now, if you need to serve 1e6 clients with threads, and those are 1MB stack threads, then you'll be using 1TB of your VM space, which... is almost certainly going to have some performance issues (MMU table size issues at the very least). If you splay your stacks on the heap as linked lists of stack chunks then you might get away with having a very large (and fragmented) heap with large page table entries, which might be a win.

I think approaches on the CPS side of the spectrum will be generally better than this. No, I don't study this and I don't have numbers. Yes, CPS in general means allocating closures on the heap so that some state does live splayed all over rather than compressed, but it doesn't have to be so. But often you'll have only a handful of such closures, and the language could understand that they are one-time use closures (hello Rust) so that no GC is needed.

I've written a small (proprietary) HTTP server that is hand-coded CPS -- specifically it supports hanging-GETs with Range: bytes=0- of regular files as a form of tail -f over HTTP, which is great for log files. That implementation has a single object per GET that has all the state needed, and the only other place state lives is in epoll event registrations (which essentially are the closures, and they are very small, and only one per-connection). Granted, this is a very simple application, and it would be a lot more complicated if, for example, it had to do async I/O directly on a block device to implement a filesystem in the same process -- that would require more care to keep the state compressed.

So in general I'm for CPS. But it's generally true that CPS solutions cost more dev time, and that can be prohibitive. The memory footprint cost difference will be a linear factor, which does not trivially justify the additional dev cost. Then again, if you'll be running lots and lots of instances with lots and lots of clients, the run-time savings can then easily be gargantuan compared to the dev costs -- but no one measures this, and by the time you wish you'd used CPS it will be too late and reimplementation costs prohibitive. Then again, async/await might fit the bill well enough most of the time.

Re: Java Virtual Threads Preview

#250
post #207

Earlier quoted context omitted.

> Any solution towards the thread side of the spectrum will yield significantly larger memory footprints than solutions towards the CPS side of the spectrum. The community-at-large decided that hand-tuning garbage collection was too finicky and not worth it, even though it obviously 'costs' memory. I'm frankly at a loss as to why so, so, so many blogposts and tech experts are all-in on the CPS-side of this argument;…

Very thought provoking. A few of my thoughts: A GC does not obviously cost memory. It might, or it might not. Both a GC and a traditional memory allocator have hidden costs. A GC with movable objects can sometimes do better, because it can manage fragmentation. I prefer a message-passing style; on which side of the spectrum would this fall? My experience with green threads is libraries that make I/O operations look l…

In CPS the continuations (closures) have to be allocated on the heap, but generally they are one-time use only, which means no GC is needed for them. Hello Rust.
Post reply on HN