14 ms·
The biggest feature in Java 21 is the release of Virtual Threads: https://openjdk.org/jeps/444 https://openjdk.org/jeps/444 For some reason, this is missing fr
by northern-lights 3y ago
The biggest feature in Java 21 is the release of Virtual Threads: https://openjdk.org/jeps/444 https://openjdk.org/jeps/444
For some reason, this is missing from the article. If there was any feature that would sway existing Golang developers to switch to Java, it would be this. It would perhaps also convince the haters of the reactive-style concurrency patterns.
- mongol 3y agoI wonder what will happen with these patterns now. They seem to have been invented to work around the problems with regular threads. Will new patterns emerge, or will the reactive patterns be ported to run on virtual threads?
- bberrry 3y agoThe reactive patterns are now obsolete and will die. And good riddens I say.
- insanitybit 3y ago`Executor.newVirtualThreadPerTaskExecutor` versus `go` really gets to the heart of why I think that Go developers aren't going to be switching. edit: Sorry, it's actually: try (var executor = Executors.newVirtualThreadPerTaskExecutor()) { executor.submit(...) ) instead of `go`
- kaba0 3y agoSo basically executor.submit(). And you still have a language that is significantly less verbose than go, objectively.
- insanitybit 3y agoYes, if you ignore more than half of the code it's quite concise.
- kaba0 3y agoHow many thread pools do you want to use? You only need that once.
- ivan_gammel 3y agoWrap it in class Go { static void go(…) } and it will look better with “import static”
- insanitybit 3y agoI assume `Go` would have to be Closeable and you'd still need the try-with-resources, right?
- kaba0 3y agoYou don't need a try-with-resources, you can manually call close if you want, or has to work in a non-lexical scope. But you often want the concurrently running threads to return some results, that try-with-resources is part of the structured concurrency that helps you with closing off a branching point, similarly to how we use while loops instead of gotos. `go` in itself corresponds to `goto` basically, with many of the same negatives.
- ivan_gammel 3y agoMaybe you re-read my comment, check the signature of Go::go() and think again?
- deleted 3y ago[deleted]
- erik_seaberg 3y agoYou’re likely to need a lot of boilerplate that “go” statement won’t generate: pass and wait for completed results, report errors, timeouts, cancellation, bounded parallelism, pushback, service monitoring.
- insanitybit 3y agoMy comment is perhaps too glib. I'm not trying to say that Go is better, I frankly like Java more. I only mean that if I'm in a Go mindset and I read the linked document on virtual threads, and I see that code example, I'm going to close the tab.
- deleted 3y ago[deleted]
- mattbee 3y agoStarting a virtual thread in Java isn't that clumsy: Thread.ofVirtual().start(() -> System.out.println("Hello"))
- zaphirplane 3y agoThe go example is missing the channels, select, wait group, context, cancellation Doesn’t sound like a fair comparison thou the Java version is missing things
- insanitybit 3y ago> The go example is missing the channels, select, wait group, context, cancellation The Java version would require all of those in the exact same way though.
- za3faran 3y agoJava has structured concurrency in the works, which will not be much more verbose, unlike golang.
- deleted 3y ago[deleted]
- foolfoolz 3y agogo will always lose vs java when it comes to code verbosity
- lenkite 3y agoExtend that to a full function and the Go code will be 2x more verbose than Java with all the `if err != nil` stuff.
- mike_hearn 3y agoIf you want to use that with more concise syntax, there is Kotlin for that. In which case abstracting that is one line of code tucked away in a utility file: fun <T> go(body: ExecutorService.() -> T): T = Executors .newVirtualThreadPerTaskExecutor() .use(body) Now you can write: val result = go { val result1 = submit { slowOp() } val result2 = submit { blockingOp() } result1.get() + result2.get() } or words to that effect. You can also reduce it a lot in Java too, as mentioned by another commenter. class Shortcuts { static <R> R go(Function<ExecutorService, R> task) throws RuntimeException { try (....) { return task.apply(service) } } } and then you can write: var result = go(service -> { var result1 = service.submit(() -> slowOp()); var result2 = service.submit(() -> blockingOp()); result1.get() + result2.get(); }); using static imports. Now if you're making a cultural point then sure, Java APIs tend to be named quite explicitly. It has advantages when searching or auto-completing, and it's easy to wrap with aliases if you want to abstract a boilerplate pattern away.
- jayd16 3y agoI don't think Golang devs are waiting to switch to Java if only making a lot of threads was easier. Honestly, its way too early. Virtual Threads will need a a "killer app" (in this case a killer framework) to pull in devs.
- kaba0 3y agoLike Helidon Nima, Micronaut, Quarkus or recently, Spring?
- jayd16 3y agoI haven't really used or heard of the others but Spring was already quite good and you really didn't need to think about threads very much. This might help some benchmarks but, again, who is pining for "Spring but with more threads?" I'm thinking something that would be a clear differentiater such as a multithreaded GUI framework.
- deleted 3y ago[deleted]
- bcrosby95 3y agoThe great thing about virtual threads is they're basically a drop in replacement for threads.
- za3faran 3y agoFor cases that are IO bound yes. Threads still have their place (another thing that golang doesn't have).
- cgh 3y agoJava 21 also previews structured concurrency (https://openjdk.org/jeps/453 https://openjdk.org/jeps/453), which uses the virtual thread implementation. It seems really nice, at least from reading the examples, and removes a number of pain points when dealing with thread-based concurrency.
- impulser_ 3y agoI don't think any existing Go developer is going back to Java. I worked with Java for 10 years and switched to Go and I will never go back. This is mostly because applications and libraries are so hard to reason about and understand due to inheritance, packaging, OOP, build tools ect compared to Go. Go is simple. It's easy to understand, read, and maintain. The packaging is like how you would package files on your computer in single folders. The tooling is built into the language. You don't need a IDE like IntelliJ just to make it feel reasonable to work with. Maybe all of this has changed, but most of the libraries I see in Java today still look like this.
- kaba0 3y ago> This is mostly because applications and libraries are so hard to reason about and understand due to inheritance, packaging, OOP, build tools ect compared to Go. You are just at the early phase of the project. > Go is simple. It's easy to understand, read, and maintain My opinion is that Go is too simple, to the point that it hinders understanding and readability. 4 nested loops with random mutability is much worse than a clear Stream api "pipeline". The 31st if err check will not be actually handling the underlying problem, while you can't forget about Exceptions -- even if they do bubble up to the main app, you will clearly get an actionable stacktrace. > The tooling is built into the language This has benefits, I will give you that. At the same time, I think all these new build tools are anemic and can't be used for anything more complex than interacting with the same language's standard dependencies. Gradle is not sexy, but is actually capable of doing any kind of build.
- nonethewiser 3y agoIm convinced Go is just an incomplete language masquerading as a simple one.
- acje 3y agoI wonder if replacing the type system in Go with the one in Rust and adding native Actor model support would be doable. Or if GC and compile time would regress too much. Modern languages without good sum types just seems like such a lost opportunity to me.
- imetatroll 3y agoNo thank you. There is limited time in the day and go fills my needs. Go, Rust, Ruby. These three cover all cases.
- quickthrower2 3y agoAdd Python to that list (for the ecosystem) and JS (for front end web dev)
- belfthrow 3y ago[flagged]
- g9yuayon 3y ago> If there was any feature that would sway existing Golang developers to switch to Java, it would be this. Not sure about this, but a trajectory question: why does the Go community have so few concurrent containers but Java community does? I mean, even `sync.Map` is specialized for two specific use cases instead of like Java's ConcurrentMap that is of general purpose. And In Java there are concurrent sets, queues, barriers, phasers, fork-join pools, and etc. I'd assume that even with Go's go routines, we can find great use of such containers, right? At least fork-join is not that trivial to implement. And using mutex everywhere seems just so... low level. I understand that there are 3rd-party implementations, but concurrency is so tricky to get right that I would be really hesitant to adopt a 3rd-party package, unless it is as mature as Java's JCTools or Google Guava, both of which are also backed by a large number of users and developers.
- segfaltnh 3y agoBecause the predominant patterns are to do concurrency with message passing, so having multiple goroutines trying to mutate the same container is the exceptional case (though as you say, mutexes are the answer when needed). Another reason is containers are embedded features not stdlib, which has huge implications to how willing someone is to go against the grain, for better and worse.
- throwaway2037 3y agoWhat concurrent data structures that Google Guava offer than the standard library does not?
- adamsb6 3y agoWill that also make existing Sway developers go?
- waffletower 3y agoFrom my vantage as a Clojurist, virtual threads on the JVM seem to have very minimal benefits. All I can think of at the moment, is that we could have thread-safe JDBC connectors: https://medium.com/oracledevs/introduction-to-oracle-jdbc-21c-driver-support-for-virtual-threads-189b918c56f4 https://medium.com/oracledevs/introduction-to-oracle-jdbc-21...
- eduction 3y agoI mean couldn’t you have the performance equivalent of core.async’s go except with the ability to take across cross function boundaries? That seems pretty huge.
- kryptonomist 3y agoGo almost instant build time is a huge productivity boost when compared to Java. You get both the solidity of a typed language, and the development speed of interpreted languages (py, js).
- troupo 3y agoJava's build times are very fast. Java's build tools are anything but. And I'm surprised no one is doing anything about it.
- palata 3y agoThat's because everybody is busy shipping full web browsers with a hard-coded website inside and calling that an "app".
- lenkite 3y agoIf you are leveraging Maven, use mvnd during development: https://github.com/apache/maven-mvnd https://github.com/apache/maven-mvnd
- kaba0 3y agoGradle, when the daemon is runnning is very fast, people just often fck up their build scripts to include config-time run functionality, which is just all around a stupid thing to do. It only ever runs tasks that actually have to be run, has integration with javac, can work in parallel, and even has cross-company build caches if needed. Also don't forget that Java can do hot reloads with the debugger, or with tools like JRebel. Certain frameworks support it 100% and it will be much much faster than whatever go does.
- troupo 3y agoI've never seen Gradle run fast, even with the daemon running. Gradle itself can take multiple seconds to startup. God knows what it's doing.
- 3y ago
- brightball 3y agoJava 21 has me anticipating the next JRuby release because of Virtual Threads. Charles Nutter gave a talk about JRuby in August where he showed a demo of the impact on Ruby fibers and it’s pretty significant. There’s a lot that I really like about the JVM and it’s tooling, I just don’t like writing Java code anymore. JRuby kinda gives the best of both worlds. Here’s the talk. Virtual thread demo is around the 45 minute mark. https://youtu.be/pzm6I4liJlg?si=GtxQ4MThEaNDfC67 https://youtu.be/pzm6I4liJlg?si=GtxQ4MThEaNDfC67
- ksec 3y agoWondering if anyone is using JRuby on Rails in production.
- brightball 3y agoHe listed off a bunch during the talk.
- kaba0 3y agoHow does jruby relate to truffleruby?
- brightball 3y agoHe actually talks about that during the video as well. Short answer is “it depends”. IIRC Truffle is dramatically faster in some benchmarks but slower in others. And there are some usability aspects of the language that are negatively impacted.
- sideeffffect 3y agoI think he shows the performance of running JRuby on top of GraalVM. GraalVM uses Graal (the JIT compiler) in place of C2 (the JIT from HotSpot). But TruffleRuby is something different. It is another Ruby implementation (just like JRuby is a Ruby implementation) using the Truffle framework. And Truffle framework requires to be run on GraalVM.
- 3y ago
- osigurdson 3y agoI once posted an Ask HN: what are your build times. A golang developer stated their 25 million line project compiles in less than half a second. If that is really the case, I must say, this is very impressive and potentially a reason to switch from other languages.
- kaba0 3y agoJava compiles very fast especially with a running gradle daemon, definitely on comparable levels. It also supports hot reloads to a degree. Also, was that a clean build?
- lenkite 3y agoIsn't this an exaggeration ? I have a 100k line go project and it takes several seconds to compile. No idea how a 25m line project compiles in less than half a second.
- peterashford 3y agoI work on a product written in Go which is considerably smaller than 25 million lines and our compile times are... really... really long. I really don't believe that claim at all. If it's true, I would love to see how it's done because that is SOOO far away from my daily experience.
- osigurdson 3y agoI was skeptical as well. Thanks for providing feedback. I suspect the way they were counting lines was wrong as 25M lines is a very large project in its own right.
- jjav 3y ago> The biggest feature in Java 21 is the release of Virtual Threads Is there a good honest writeup on why is this interesting? Very curious. The earliest JVMs had this, green threads. Performance was terrible so it was eventually dropped. I want to fully utilize every CPU and every core I have, why do I want green/virtual threads again?
- kaba0 3y agoThe JVM automagically swaps out blocking network calls executing in a virtual thread to a non-blocking implementation, so potentially many other requests can be served in the same time. So you get the benefit of async frameworks, with none of the negatives: the blocking model is trivial to reason about, read, maintain, and works perfectly with tooling (you won’t get an exception in some WhateveScheduler, but at the exact line where it actually happened. Also, can step through with a debugger).
- jjav 3y agoThanks. Any good books that cover the current java performance landscape but is grounded in the history of what came before? I used to be heavily involved in java-based server performance and scalability work back in the 90s and 00s but have been working on other things the last decade. But it would be fun to learn more about where things stand.
- tommiegannert 3y agoFor me, it's the difference between code structure and resource usage. Green threads are for a cleaner code structure. async/await comes quite close, but requires function coloring, creating high coupling. The threads have to have low overhead, so that I don't have to think about whether I should create a new one or not. Kernel threads are for parallelism and scaling across cores.
- mike_hearn 3y agoIt's not the same. The earliest JVMs weren't really thread safe at all but machines were single core so it didn't matter, you could just cooperatively multi-task. Later HotSpot became thread safe (and fast - a rare achievement), so started using real OS threads so it could go multi-core. Virtual threads are M:N threading. There are multiple native threads so you can exploit all the cores, and also user-space runtime managed stacks so you can pack way more threads into a process.
- wscp-dev 3y agoThat is true, but there are many who have discussed that. I wanted to bring some attention to the new syntactic changes Java brings that can help with implementing better logic.
- winter_blue 3y agoI wonder: are virtual thread at the JVM level? If so, would Kotlin (and other JVM languages) be able to leverage virtual threads to improve (e.g. produce more optimal JVM bytecode) for their async functionality?
- midoBB 3y agoIt is a JVM level feature but the Scala guys at ZIO are not that excited about it IIRC.
- krzyk 3y agoIt depends what one needs. VT are nice, but I don't use threads much, so it is a cool feature I won't use. For me bigger feature is pattern matching for switch and records.
- deleted 3y ago[deleted]