Live data from Hacker News

Java Virtual Threads Preview

openjdk.java.net

231–240 of 270 posts

Re: Java Virtual Threads Preview

#231
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…

Thank you a ton for posting this! I've been doing this for most/all of my life and it didn't really make sense till now. I've had people explain it before but it didn't really make sense. Here's what I got from what you wrote (please correct me if this is wrong / kinda off in some way)

For most words, the possessive form is "'s"

For pronouns (including it) there are different rules. He becomes his, she goes to hers, it goes to its.

Also, words that already end in s don't get the " 's " treatment.

(Question - for words that end in "s", we put the apostrophe after the existing, ending 's', yes?)

Thanks again for posting this - viewing the possessive form of it as (yet another English language) exception to the normal rule of " 's " is really helpful.

Re: Java Virtual Threads Preview

#232
post #139

Earlier quoted context omitted.

Maybe? it depends how you use them... any asynchronous operation will require memory, and that memory has to go somewhere. In CPS it goes on the heap... in the threaded style you have a stack you can put it on. This probably will waste some memory, though not as much as you might think. On the other hand, you can also reclaim the stack memory as soon as the operation finishes. The CPS technique creates garbage that a…

Green threads by definition cannot use OS stack and must allocate their stack memory on heap. Although this memory can be reused, as it is known from Go to avoid performance bottlenecks at least for Go code is better to allocate the stack as single continues block and copy the stack to a bigger block when thread’s stack reaches the current stack size. But then the whole stack space is pinned to the thread and cannot…

Thread stacks are not OS level objects, at least in linux you just malloc or anon-mmap some memory and pass that to clone() or you own green thread implementation.

Re: Java Virtual Threads Preview

#233
post #218

Earlier quoted context omitted.

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…

The problem with function coloring is that it divides the language for no good reason. Should there really be two names for the same sleep function, just because one is blocking and the other is not? As for a return type, that’s just a leaky abstraction imo (especially for voids, like is a blocking call returning nothing different than an async call returning a Future void?) As for loom, due to it running all in a ru…

Personally, in JavaScript I like that you can mix and match imperative and asynchronous code using Promise instances. It lets you handle asynchronous control flow in a purely synchronous function.

However in other languages, having functions be of a different 'color' is far more painful. In Python for example, a synchronous function has to setup an event loop manually before it can run an asynchronous function. The call works, but nothing is 'running' without the event loop. Additionally, the asynchronous function may have been written to work with a particular eventloop (e.g. trio vs curio), and thus you have to use that type.

If non-blocking code has a standardized control state like Javascript, I think it's better to be explicit about async vs sync.

Re: Java Virtual Threads Preview

#234

Is this like .NET tasks? If so, what’s the async story here? Does it involve function colouring like in .NET?

The doco explains it quite well, so I won't repeat it here. It's solving the same problem that async does, but it does it with virtual threads instead. The idea is that functions aren't coloured, and that normal threaded code will "just work". I see some benefits of this approach, but I feel that what all of the solutions (Java, C#, Rust, etc...) are missing is structured concurrency [1], without which madness and el…

In practice, I suspect structured concurrency will frequently requiring using the escape hatch for scenarios where a long lived background like task really is the right fit.

But the scape hatch works by.... coloring functions! Specifically if a function needs to spawn a longer lived background task, it needs to take a nursery parameter.

If a function wants to call a function that might spawn a long lived function, it needs to either own the lifetime of said nursery, or more commonly accept a nursery as a a parameter, and pass in the supplied one.

In practice with java, the nursery concept (StructuredExecutor) will only be used for those cases where it is actually helpful, (i.e. where you really want the function call to not return until all concurrent tasks are finished), and everywhere else, like background tasks, existing primitives will be used.

And all nurseries/StructuredExecutor is buying you is the ability structurally enforcing joining of the relevant virtual threads. It lets you avoid some of the common mistakes in structuring such code, but I'm not convinced that is where the eldritch horrors of concurrent code debugging live.

I think the real eldritch horrors come from buggy attempts to implement low lock code, failing to realize that locks or other synchronization is needed when accessing a certain variable, etc. Basically race condition type situations.

I personally almost never have had substantial concurrency issues related to failing to join my concurrent tasks.

Re: Java Virtual Threads Preview

#235
post #45

Earlier quoted context omitted.

...and then many of us may not put it in production until the next LTS anyway... (...aside from those that are perpetually stuck on Java 8 anyway.)

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?

Re: Java Virtual Threads Preview

#236

Earlier quoted context omitted.

As part of project Loom, these green threads were called Fibers, not VirtualTheads. Did they change the name?

Yes. As ideas were prototyped it became clear that Fibers needed to be Threads or there would be too many rough edges regarding compatibility and concepts that developers would need to keep in their heads.

Thanks for the explanation. A little hard for those who do not follow it closely.

Re: Java Virtual Threads Preview

#237
post #189

Earlier quoted context omitted.

> With a preemptive scheme like Java virtual thread, you will still have to protect shared data and have ways to coordinate and synchronize like mutex, locks and all that. As far as I know there is nothing preventing race conditions and dead/live locks in case of coroutines either, isn’t there? Like of course if you have 1 thread these issues won’t come up, but with true parallelism, this model in itself doesn’t prot…

It doesn't prevent it, but it can help with synchronization. If you have two coroutines writing to the same variable, but they yield to each other, you know they won't ever both run at the same time. You also know if you spawn multiple coroutines that they won't yield except where they call yield, so everything before and after the yield you know will be atomic.

> If you have two coroutines writing to the same variable, but they yield to each other, you know they won't ever both run at the same time.

But that won’t be parallel just concurrent, and in case of cooperative “threads”, you could have probably written it in a more readable single threaded way, as that’s pretty much just calling two functions back and forth.

Your second point also only works when you have a single thread of execution, otherwise concurrency will entail parallelism and all the usual problems will become apparent.

Re: Java Virtual Threads Preview

#238

I am lost here. the non-goal mentioned here are actually worth taking as goals to be fulfilled so that every other language and library ecosystem which runs on JVM will get benefited. Non-Goals:- It is not a goal to change the existing implementation of platform threads, that represent Operating System (OS) threads. It is not a goal to automatically convert existing thread construction to virtual threads. It is not a…

Those all make sense: - Native threads are great. They have a lot of uses, why touch them - Automatic conversion will break a lot of stuff and eliminate some of the benefits of native threads. Being able to use an API/implementation that is *almost* the same is a huge beneift - The memory model is a completely separate thing that Java worked on for decades. You don't want to touch that and you don't need to - Inter-t…

While automatic conversion might be off the table, any library that expects (or allows) the caller to supply the ThreadFactory used to created thread will should make switching over pretty easy. Just construct the factory with `Thread.ofVirtual().factory()`, and provide it to the library. And if it is code you own, spawning threads, then switching over should be a pretty mechanical process.

On the memory model: I'd argue that technically the memory model would be implicitly updated to treat these virtual threads the same as classic threads. Which is a very minor update. Beyond that, in order to maintain that memory model, the implementation will need to ensure proper barriers are used on pausing and resuming virtual threads, so that a virtual thread resumed on a different physical core is guaranteed to see any of its previous writes (as would be expected within a "single thread").

Re: Java Virtual Threads Preview

#240
post #237

Earlier quoted context omitted.

It doesn't prevent it, but it can help with synchronization. If you have two coroutines writing to the same variable, but they yield to each other, you know they won't ever both run at the same time. You also know if you spawn multiple coroutines that they won't yield except where they call yield, so everything before and after the yield you know will be atomic.

> If you have two coroutines writing to the same variable, but they yield to each other, you know they won't ever both run at the same time. But that won’t be parallel just concurrent, and in case of cooperative “threads”, you could have probably written it in a more readable single threaded way, as that’s pretty much just calling two functions back and forth. Your second point also only works when you have a single…

Threads still have the issue of synchronization and atomicity even when only concurrent and not parallel.

That is, assuming you had a single core CPU, with threads you'd still need to synchronize things when implementing concurrency. Coroutines have a more explicit synchronization from their natural ping/pong as you yield which could be said to tend to be safer in the average case.

I think you're maybe conflating something. If two things write to the same global variable for example, that can never be parallel, but it can be concurrent. With threads, the writes to the variables need to be guarded with some synchronization mechanisms, if you forget you'll have bugs.

With coroutines, they will be naturally synchronized by the yield points.

> you could have probably written it in a more readable single threaded way, as that’s pretty much just calling two functions back and forth

It's not just calling two functions back and forth, the coroutines retain state and continue where they yielded. Each time they yield they do not consume additional stack frames.

Post reply on HN