Live data from Hacker News

Thread Pools on the JVM

gist.github.com

71–80 of 120 posts

Re: Thread Pools on the JVM

#71
post #54
post #53

Earlier quoted context omitted.

Java had M:N green thread models a LOOOOONG time ago. And Linux tried M:N thread implementations specifically to improve thread performance. In both cases, it turned out that just using 1:1 native threads ended up being a net win.

i am not aware of M:N thread builtin in Java even from long time ago, at least not in a way that you could control N

The old JDK 1.1 Developer's Guide had a page on the different thread models: https://docs.oracle.com/cd/E19455-01/806-3461/6jck06gqk/inde...

At the time, Solaris had the only "certified" JVM that did M:N threads, so they really liked to make a big deal about it.

You could control N through a JNI call to thr_setconcurrency. Not portable, but it worked. That particular capability was almost always not helpful.

Re: Thread Pools on the JVM

#72
post #52

Earlier quoted context omitted.

> That, unfortunately, is really heavy memory wise and on the OS context switcher. So, there was a time where a broad statement like that was pretty solid. These days, I don't think so. The default stack size (on 64-bit Linux) is 1MB, and you can manipulate that to be smaller if you want. That's also the virtual memory. The actually memory usage depends on your application. There was a time where 1MB was a lot of mem…

>>> The default stack size (on 64-bit Linux) is 1MB The default thread stack size is 8 or 10 MB on most Linux. The exception is Alpine that's below 1 MB.

To clarify, the 1MB is the default stack size for threads with the JVM on 64-bit Linux.

Search for "-Xss": https://docs.oracle.com/en/java/javase/16/docs/specs/man/jav...

Re: Thread Pools on the JVM

#73
post #22
post #2

Loom can't land fast enough! The current issue the JVM has is that all threads have a corresponding operating system thread. That, unfortunately, is really heavy memory wise and on the OS context switcher. Loom allows java to have threads as light weight as a goroutine. It's going to change the way everything works. You might still have a dedicated CPU bound thread pool (the common fork join pool exists and probably…

You are ignoring the downside to green threads which is that it’s cooperative. If the thread doesn’t yield control back to the event loop then the real OS thread backing the loop is now stuck. Which leads to dirty things like inserting sleep 0 at the top of loops and dealing with really unbalanced scheduling of threads don’t hit yields often enough. Plus with loom it might not be obvious that some function is a yield…

:) sleep 0! I was trying to see if there is a way to preempt stuck threads (infinite loops etc), and wrote a small while loop replacement

  pwhile(()-> loop predicate, ()-> {loop body});

All it does is add a thread.isinterrupted check to the predicate. At this point, best to switch to Erlang !

Re: Thread Pools on the JVM

#74
post #14

Earlier quoted context omitted.

What benefits does loom provide vs using something like cats-effect fibres?

For the team that I am in, I can see a huge productivity boost if my teammates can write in direct style instead of wrapping their heads around monads.

Scala for-expressions make it pretty easy to write "direct style" code. Someone on the team should probably understand whats going on, though. I've had decent success with ZIO on my team, and it seems perfectly teachable/learnable.

Re: Thread Pools on the JVM

#75
post #52

Earlier quoted context omitted.

> That, unfortunately, is really heavy memory wise and on the OS context switcher. So, there was a time where a broad statement like that was pretty solid. These days, I don't think so. The default stack size (on 64-bit Linux) is 1MB, and you can manipulate that to be smaller if you want. That's also the virtual memory. The actually memory usage depends on your application. There was a time where 1MB was a lot of mem…

> So, there was a time where a broad statement like that was pretty solid. That time is approaching 20 years old at this point, too. Native threads haven't been "expensive" for a very, very long time now. Maybe if you're in the camp of disabling overcommit it matters, but otherwise the application of green threads is definitely a specialized niche, not generally useful. > In the broad set of use cases though, switchi…

> That time is approaching 20 years old at this point, too. Native threads haven't been "expensive" for a very, very long time now.

It depends on the context, but yes. I worked on stuff throughout the 2000's where we ran into scaling problems with thread based concurrency models. At the time, running 100,000 threads was... challenging. But yeah, by 2010 we were talking about the C10M problem, because the C10K problem wasn't a problem any more. There are some cases where you really do need to handle 10's or 100's of millions of threads, but there aren't a lot of them.

> Maybe if you're in the camp of disabling overcommit it matters, but otherwise the application of green threads is definitely a specialized niche, not generally useful.

Yup, but everyone is still stuck on the old mental model of "threads are bad", partly driven by the assumption that whatever is being done to handle those extreme cases is what one should be doing to address their own problem space. :-(

> I'd go even further and say it'll be a net-loss in most cases, especially with modern complications like heterogeneous compute.

Even more so if you're doing polling based I/O rather than a reactive model. The look on people's faces when I point out to them that there's good reason to think that for the scale they are working at, they'll likely get better performance if they just use threads to scale...

It's so weird how we talk about the context switching costs between threads without recognizing that the thread does the poll is not the same thread that processed the IO request in the kernel.

Re: Thread Pools on the JVM

#76
With Python at first I was scared of GIL being single threaded, now I'm used to it and it works great. Thousands of threads used to be normal for my old Java projects but seems crazy to me now.

Re: Thread Pools on the JVM

#77
post #22
post #2

Loom can't land fast enough! The current issue the JVM has is that all threads have a corresponding operating system thread. That, unfortunately, is really heavy memory wise and on the OS context switcher. Loom allows java to have threads as light weight as a goroutine. It's going to change the way everything works. You might still have a dedicated CPU bound thread pool (the common fork join pool exists and probably…

You are ignoring the downside to green threads which is that it’s cooperative. If the thread doesn’t yield control back to the event loop then the real OS thread backing the loop is now stuck. Which leads to dirty things like inserting sleep 0 at the top of loops and dealing with really unbalanced scheduling of threads don’t hit yields often enough. Plus with loom it might not be obvious that some function is a yield…

Agreed, but you have other single-threaded server languages like NodeJS which have the same problem (a new request can only be handled if the current request gives up control, usually waiting for IO) and people have figured out how to handle it.

I see Project Loom as really providing all the benefits of single threaded languages like Node (i.e. tons of scalability), but with an easier programming model that threads provide as opposed to using async/await.

Re: Thread Pools on the JVM

#78
post #51

Earlier quoted context omitted.

Unless I'm misunderstanding, virtual threads are preemptive: https://cr.openjdk.java.net/~rpressler/loom/loom/sol1_part1....

By the OS, not by the scheduler see https://cr.openjdk.java.net/~rpressler/loom/loom/sol1_part2....

What about pron's comments here then? https://news.ycombinator.com/item?id=27885569

> Second, Loom's virtual threads can also be forcibly preempted by the scheduler at any safepoint to implement time sharing

Re: Thread Pools on the JVM

#79
post #52
post #2

Loom can't land fast enough! The current issue the JVM has is that all threads have a corresponding operating system thread. That, unfortunately, is really heavy memory wise and on the OS context switcher. Loom allows java to have threads as light weight as a goroutine. It's going to change the way everything works. You might still have a dedicated CPU bound thread pool (the common fork join pool exists and probably…

> That, unfortunately, is really heavy memory wise and on the OS context switcher. So, there was a time where a broad statement like that was pretty solid. These days, I don't think so. The default stack size (on 64-bit Linux) is 1MB, and you can manipulate that to be smaller if you want. That's also the virtual memory. The actually memory usage depends on your application. There was a time where 1MB was a lot of mem…

Your words might be true, but the world jumped on async wagon long time ago and going all in. Nobody likes threads, everyone wants lightweight threads. Emulating lightweight threads with promises (optionally hidden behind async/await transformations) is very popular. So demand for this feature is here.

I don't know why, I, personally, never needed that feature and good old threads were always enough for me. It's weird for me to watch non-JDBC drivers with async interface, when it was a common knowledge that JDBC data source should use something like 10-20 threads maximum (depending on DB CPU count), anything more is a sign of bad database design. And running 10-20 threads, obviously, is not an issue.

But demand is here. And probably lightweight threads is a better approach than async/await transformations.

Re: Thread Pools on the JVM

#80
post #78

Earlier quoted context omitted.

By the OS, not by the scheduler see https://cr.openjdk.java.net/~rpressler/loom/loom/sol1_part2....

What about pron's comments here then? https://news.ycombinator.com/item?id=27885569 > Second, Loom's virtual threads can also be forcibly preempted by the scheduler at any safepoint to implement time sharing

For me, preemption by the Java scheduler is not currently supported but may be added in the future, after all the goroutine were not preempted at the beginning in Go.

The whole quote

> Second, Loom's virtual threads can also be forcibly preempted by the scheduler at any safepoint to implement time sharing. Currently, this capability isn't exposed because we're yet to find a use-case for it

I believe it's a reference to [1] but i may be wrong.

[1] https://download.java.net/java/early_access/loom/docs/api/ja...

Post reply on HN