core.async and Virtual Threads
core.async 1.9.847-alpha3 is now available. This release reverts the core.async virtual thread implementation added in alpha2 , and provides a new implementation ( ASYNC-272 ). Threads must block while waiting on I/O operations to complete. "Parking" allows the platform to unmount and free the underlying thread resource while waiting. This allows users to write "normal" straight line code (without callbacks) while consuming fewer platform resources. io-thread execution context io-thread was added in a previous core.async release and is a new execution context for running both blocking channel operations and blocking I/O operations (which are not supported in go ). Parking operations are not allowed in io-thread (same as the thread context). io-thread uses the :io executor pool, which will now use virtual threads, when available. If used in Java without virtual threads (< 21), io-thread continues to run in a cached thread pool with platform threads. With this change, all blocking operations in io-thread park without consuming a platform thread on Java 21+. go blocks Clojure core.async go blocks use an analyzer to rewrite code with inversion of control specifically for channel parking operations (the ! async ops like >! ). Other blocking operations ( !! channel ops or arbitrary I/O ops) are not allowed. Additionally, go blocks are automatically collected if the channels they depend on are collected (and parking can never progress). The Java 21 virtual threads feature implements I/O parking in the Java platform itself - that capability is a superset of what go blocks provide by

core.async 1.9.847-alpha3 has been released, marking a significant update to the virtual thread implementation. This version reverts the changes introduced in alpha2 and introduces a new implementation based on the ASYNC-272 feature. The core idea behind this update is to enhance the handling of blocking I/O operations while optimizing resource usage.
In traditional multi-threaded applications, threads must block when waiting for I/O operations to complete. This can lead to a high number of idle threads consuming significant system resources. The new implementation addresses this issue by introducing a concept called "parking." Parking allows the platform to unmount and free the underlying thread resource while waiting for I/O operations to finish. This innovation enables developers to write straightforward, linear code without the need for callbacks, all while reducing the overall resource footprint.
A key component of this release is the io-thread execution context, which was introduced in a previous core.async release. io-thread is designed to handle both blocking channel operations and I/O operations that are not supported in the go blocks. Importantly, parking operations are not permitted in the io-thread context, adhering to the same constraints as the thread context.
The io-thread execution context utilizes the :io executor pool, which now leverages virtual threads when available. For Java environments without virtual threads (versions below 21), io-thread continues to run in a cached thread pool with platform threads. With this change, all blocking operations in io-thread park without consuming a platform thread on Java 21 and later.
The go blocks in Clojure core.async have also been updated to integrate with the new virtual thread implementation. These blocks use an analyzer to rewrite code with inversion of control specifically for channel parking operations, such as the ! async ops like >!. However, other blocking operations, such as !! channel ops or arbitrary I/O ops, are not supported. Additionally, go blocks are automatically collected if the channels they depend on are collected, ensuring that parking can never progress in such cases.
The Java 21 virtual threads feature introduces I/O parking capabilities directly into the Java platform, which is a superset of the functionality provided by go blocks. This means that virtual threads can handle all blocking I/O operations, not just those related to channel parking. While virtual threads share many similarities with regular threads, there is a crucial difference in their semantics. Unlike go blocks, virtual threads must terminate ordinarily and will keep referenced resources alive until they do.
Due to this difference in semantics, go blocks remain unchanged and continue to use the go analyzer and run on platform threads. If users wish to take advantage of the benefits and constraints of virtual threads, they can convert go blocks to io-thread execution contexts. This conversion allows them to leverage the optimized resource management and efficient handling of blocking I/O operations offered by the new core.async implementation.
In summary, core.async 1.9.847-alpha3 introduces a new virtual thread implementation that enhances the management of blocking I/O operations and reduces resource consumption. The io-thread execution context, combined with the updated go blocks and integration with Java 21's virtual threads, provides developers with a powerful set of tools for writing efficient, concurrent applications in Clojure.










