Premise before a long period of attention JDK
The development progress of the coroutine library, but I was very busy for a period of time and rarely checked it OpenJDK
The content of the official website. Java coroutine projectLoom
(Since the project is still in the development stage,OpenJDK
Official website givenOpenjdk.java.net/projects/lo…Only a small amount ofLoom
Information related to the project) has been established prior to 2018 and has been published based onJDK17
Compile and JDK18
Compilation and other early versions of the author in the downloadLoom
Early versions of the time only foundJDK18
Compiled version:Download from:jdk.java.net/loom
Because the JDK version is too high, you can use the mainstream IDE import Loom-JDK-18+9 for code highlighting and syntax reminding, temporarily can not find a way to compile, temporarily use the JDK to execute the directory under the javac command script to compile, use Java command script to run.
A brief introduction to Loom project
Loom - Fibers, Continuations and Tail-Calls for the JVM
Copy the code
The title of the Loom project already highlights three new features introduced:
Fibers
: I saw it a few years agoLoom
The project’s test code is usedFiber
thisAPI
(Now this oneAPI
Has been removed), which stands for lightweight thread, also known as coroutine, also known as lightweight user thread, which is amazing at the momentJDK
Is actually calledVirtual Thread
Continuations
“What is the next block of code to be executed?”Tail-Calls
Tail: callVM
Level of support
The three new features are not detailed. They are currently only EA versions and are subject to change, so there is no need to elaborate on them.
Virtual Thread using
Coroutine use in the current version of Loom project does not introduce a new public VirtualThread class. Although virtualThreads do exist, this class uses the default modifier and is hidden in the java.lang package. VirtualThread is a subclass of Thread. The coroutine creation API is in the Thread class:
Coroutine use in the current version of Loom project does not introduce a new public VirtualThread class. Although virtualThreads do exist, this class uses the default modifier and is hidden in the java.lang package. VirtualThread is a subclass of Thread. The coroutine creation API is in the Thread class:
Create coroutines using this API as follows:
public static void main(String[] args) {
Thread fiber = Thread.startVirtualThread(() -> System.out.println("Hello Fiber"));
}
Copy the code
From the current source:
VirtualThread gets the parent Thread’s scheduler via Thread.currentThread(). If run in main, The parent thread of the coroutine instance in the code above is the ForkJoinPool instance (virtualThread.default_scheduler) created for the system by the default scheduler of the main thread. The input Runnable instance is encapsulated as a RunContinuation, and the scheduler ultimately executes the coroutine for timed unpark, Use the system to create instances of ScheduledExecutorService to wake up The static factory methods to create the coroutines running immediately, returns the coroutines instance If, in accordance with the above Thread. StartVirtualThread () method to create coroutines, Properties such as the name of the coroutine cannot obviously be defined. The Loom project solves this problem reasonably by introducing the Builder pattern for the Thread class:
// Create a platform Thread builder corresponding to the Thread instance
public static Builder.OfPlatform ofPlatform(a) {
return new ThreadBuilders.PlatformThreadBuilder();
}
// create a VirtualThread builder corresponding to a VirtualThread
public static Builder.OfVirtual ofVirtual(a) {
return new ThreadBuilders.VirtualThreadBuilder();
}
Copy the code
To put it simply:
The ofPlatform() method is used to create VirtualThread instances. The ofVirtual() method is used to create VirtualThread instances. The ofPlatform() method is used to create VirtualThread instances. The chain of all Setter methods for the two constructor instances is expanded as follows:
public static void main(String[] args) {
Thread.Builder.OfPlatform platformThreadBuilder = Thread.ofPlatform()
// Whether to daemon the thread
.daemon(true)
/ / thread group
.group(Thread.currentThread().getThreadGroup())
// The thread name
.name("thread-1")
Prefix + (start + 1) => prefix + (start + 1) => prefix + (start + 1)
// start > 0 overrides the name attribute configuration
.name("thread-".1L)
// Whether to enable ThreadLocal
.allowSetThreadLocals(false)
// Whether to enable InheritableThreadLocal
.inheritInheritableThreadLocals(false)
// Set the priority
.priority(100)
// Set the thread stack depth
.stackSize(10)
// Sets the exception handler not caught
.uncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
@Override
public void uncaughtException(Thread t, Throwable e) {
}
});
// thread-1
Thread firstThread = platformThreadBuilder.unstarted(() -> System.out.println("Hello Platform Thread First"));
// thread-2
Thread secondThread = platformThreadBuilder.unstarted(() -> System.out.println("Hello Platform Thread Second"));
Thread.Builder.OfVirtual virtualThreadBuilder = Thread.ofVirtual()
// Coroutine name
.name("fiber-1")
// Coroutine name prefix + start increment => prefix + start, the next coroutine name created is prefix + (start + 1)
// start > 0 overrides the name attribute configuration
.name("fiber-".1L)
// Whether to enable ThreadLocal
.allowSetThreadLocals(false)
// Whether to enable InheritableThreadLocal
.inheritInheritableThreadLocals(false)
// Set the scheduler. Executor instances, where the scheduler is a thread pool, to NULL use VirtualThread.DEFAULT_SCHEDULER
.scheduler(null)
// Sets the exception handler not caught
.uncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
@Override
public void uncaughtException(Thread t, Throwable e) {
}
});
// fiber-1
Thread firstFiber = virtualThreadBuilder.unstarted(() -> System.out.println("Hello Platform Virtual First"));
// fiber-2
Thread secondFiber = virtualThreadBuilder.unstarted(() -> System.out.println("Hello Platform Virtual Second"));
}
Copy the code
One thing you can see here is that the builder is reusable. If you want to use the builder to create threads or coroutines with the same set of parameters, you can set the name(String prefix, long start) method to define the thread or coroutine name prefix with a number greater than or equal to zero. To batch create threads or coroutines, call Builder#unstarted(Runnable task) repeatedly. Set the name to prefix + start, prefix + (start + 1), prefix + (start + 2), and so on. Coroutine creation is basically as simple as that, calling the start() method directly to run it:
public class FiberSample2 {
public static void main(String[] args) throws Exception {
Thread.ofVirtual()
.name("fiber-1")
.allowSetThreadLocals(false)
.inheritInheritableThreadLocals(false)
.unstarted(() -> {
Thread fiber = Thread.currentThread();
System.out.printf("[%s,daemon:%s,virtual:%s] - Hello World\n", fiber.getName(),
fiber.isDaemon(), fiber.isVirtual());
}).start();
// The main thread is asleepThread.sleep(Long.MAX_VALUE); }}Copy the code
Currently, the above classes cannot be compiled in mainstream IDES, so you can only compile and run them using tools in the JDK directory as follows:
I:\ j-projects \framework-source-code\fiber-sample\ SRC \main\ Java (1I: Environment\Java\ JDK18-loom\bin\javac.exe I:\J-Projects\framework-source-code\fiber-sample\src\main\java\cn\throwx\fiber\sample\FiberSample2.java
(2Execute the main method: I: Environment\Java\ JDK18-loom\bin\java.exe cn.throwx.fiber.sample.FiberSample2
Copy the code
One thing you see here, too, is that for all instances of coroutines daemon
Flag defaults totrue
It cannot be modified. ## Summary if use the Angle of taste to useLoom
Projects can be snooped in advanceJVM
How are developers building on this significant feature of coroutines to improve learningJDK
An interest in kernel code helps a lot. For now, the implementation of coroutines Loom
Project distanceRELEASE
Version of the estimated many functions need to be improved, including newAPI
And whether coroutines can be ported to the originalJUC
Used in the class libraryLoom-JDK-18+9
There are no changes to the original thread pool, etc.), so wait while you keep your eyes open.