— , . Java concurrency. concurrency-, , , .
— Project Loom. Java .
, OpenJDK Core Libraries Project, Loom , Java . Joker 2020. — .
, Java Platform Oracle, OpenJDK. Project Loom.
2017 (, 2018-). OpenJDK , . , . — — , . , .
- : , .
:
- .
- , .
- IDE , .
- , .
Java ( , JVM) :
- , .
- , ThreadLocal.
- , . step over, , .
- , , , .
, , , .
Java API java.lang.Thread. JDK , . java.lang.Thread --. , Java, JDK. . 20 , java.lang.Thread, .
C Java. . . , , ,
, .
, ,
. .
, . ,
. - , , , . , .
. , . , . . . , , . , , .
, — , . , .
, , , , . . , , .
, ?
— , ? . , , .
. , , , , ThreadLocals. . : , , , , , .
, , . , - , .
, ,
CPU, , , , IO, - . , , , .
, , . . , API, API, - — , .
API, , . API.
, , . — , . , , , — , .
, . , , . , IO. , , .
, . , . . , .
, , .
.
. , , .
, ? , ? , , . Project Loom .
API
API.
Project Loom , API? , , .
, , —
java.lang.Thread. API, JDK 1.0. , «». , , . API, , .
—
API. Project Loom, , , API fiber.
API, , . , , — . Thread.currentThread() , , .
, : « Thread.currentThread() ?» , , 2 5. — 113.
— ThreadLocals. , . Thread.currentThread() ThreadLocals, . , fiber API, Thread API, , fiber. , , Thread, .
, .currentThread() Threadlocals . «». . , , , , — , , java.lang.Thread.
, — ,
25 . API java.lang.Thread. java.lang.Thread , .
. , « » (virtual thread).
Thread — . , , . «», , , ThreadLocals .
?
. «» , green threads. JDK, 1.0.1.1 , , - . , , , .
, , . HotSpot : scoped stackful one-shot delimited continuations. HotSpot Java. , , , , IO-, , , , Java, . .
, , , . , . , .
, API Java, ,
, yield resume JDK, , .
, , .
. , 16 . , . , HotSpot .
, 256 . , —
.
, , . , . , , ,
.
IDE .
IDE , .
import ...
public class Demo {
public static void main(String[] args) throws Exception {...}
void run() throws Exception {
}
}
, , Thread.startVirtualThread().
import ...
public class Demo {
public static void main(String[] args) throws Exception {...}
void run() throws Exception {
Thread thread = Thread.startVirtualThread(() -> System.out.println("hello"));
thread.join();
}
}
«hello», . start(), .
-, , , .
void run() throws Exception {
Thread thread = Thread.startVirtualThread(Thread::dumpStack);
thread.join();
}
- .
, , , java.lang.Thread
, , , , JDK. , . , .
API. startVirtualThread()
?
, . Thread.builder()
. , : -, .
virtual(). c startVirtualThread()
, , , . , :
void run() throws Exception {
Thread thread = Thread.builder().virtual().task(() -> {
System.out.println("hello");
}).start();
thread.join();
}
}
, . , , setDaemon() setName(). .
API , Thread API . — , startVirtualThread().
ThreadFactory.
void run() throws Exception {
ThreadFactory factory = Thread.builder().name("worker-", 0).factory();
}
— , worker-0, worker-1, worker-2 . worker — , . .
, , , .
Thread API . JDK 5, ThreadExecutor API java.util.concurrent.
ThreadExecutor. , .
ExecutorService executor:
try (ExecutorService executor = Executors.newVirtualThreadExecutor()) {
}
Executors . , try-with-resources. , Loom, — ExecutorService AutoCloseable, try-with-resources.
, , , , , , , . , , . Executor' , , Executors.
.
import ...
public class Demo {
public static void main(String[] args) throws Exception {...}
void run() throws Exception {
try (ExecutorService executor = Executors.newVirtualThreadExecutor()) {
IntStream.range(0, 1_000_000).forEach(i -> {
executor.submit(() -> { });
});
}
}
String fetch(String url) throws IOException {...}
void sleep(Duration duration) {...}
}
IntStream.range(), for. executor.submit() , , . , — «Process finished with exit code 0».
, .
import ...
public class Demo {
public static void main(String[] args) throws Exception {...}
void run() throws Exception {
AtomicInteger counter = new AtomicInteger();
try (ExecutorService executor = Executors.newVirtualThreadExecutor()) {
IntStream.range(0, 1_000_000).forEach(i -> {
executor.submit(counter::incrementAndGet);
});
}
System.out.println(counter.get());
}
String fetch(String url) throws IOException {...}
void sleep(Duration duration) {...}
}
Executor, , , , . , , .
— , .
, Executor'. , URL-, . — , .
String fetch(String url) throws IOExpection {
try (InputStream in = URI.create(url).toURL().openStream()) {
byte[] bytes = in.readAllBytes();
return new String(bytes, "ISO-8859-1");
}
}
, HTTP- , .
:
void run() throws Exception {
try (ExecutorService executor = Executors.newVirtualThreadExecutor()) {
Callable<String> task1 = () -> fetch("https://jokerconf.com/");
Callable<String> task1 = () -> fetch("https://jokerconf.com/en");
String first = executor.invokeAny(List.of(task1, task2));
System.out.println(first.length());
}
}
, HTML- jokerconf.com. , , . - , , .
executor.invokeAny()
.
ExecutorService , invokeAny()
, invokeAll()
, . .
first , , .
. , — , , , String first. (). — : «200160», 200 .
, : , URL-, — URL-, , . , : 178 , — 200 .
. , - , invokeAll()
.
void run() throws Exception {
try (ExecutorService executor = Executors.newVirtualThreadExecutor()) {
Callable<String> task1 = () -> fetch("https://jokerconf.com/");
Callable<String> task1 = () -> fetch("https://jokerconf.com/en");
executor.invokeAll(List.of(task1, task2))
.stream()
.map(Future::join)
.map(String::length)
.forEach(System.out.println);
}
}
, — , , invokeAll()
. , . InvokeAll()
, , Future, . , , , . 200 178 . ExecutorService.
-. Loom CompletableFuture, . CompletableFuture, Future, :
void run() throws Exception {
try (ExecutorService executor = Executors.newVirtualThreadExecutor()) {
Callable<String> task1 = () -> fetch("https://jokerconf.com/");
Callable<String> task1 = () -> fetch("https://jokerconf.com/en");
CompletableFuture<String> future1 = executor.submitTask(task1);
CompletableFuture<String> future2 = executor.submitTask(task2);
CompletableFuture.completed(future1, future2)
.map(Future::join)
.map(String::length)
.forEach(System.out.println);
}
}
CompletableFuture- completed(). , Future . , invokeAll(), , , . . - CompletionService, - .
, , , . , , CompletableFuture, .
, , . . . , , IO-, . , IDE, , .
import ...
public class Demo {
public static void main(String[] args) throws Exception {...}
void run() throws Exception {
Thread.startVirtualThread(() ->
sleep(Duration.ofSeconds(2));
}).join();
}
String fetch(String url) throws IOException {...}
void sleep(Duration duration) {...}
}
, , . . , , .
void run() throws Exception {
Thread.startVirtualThread(() -> {
Object lock = new Object();
synchronized (lock) {
sleep(Duration.ofSeconds(2));
}
}).join();
}
, , .
, , . , , . . , , . , , . , c , . .
, .
package demo;
import ...
@Path("/")
public class SleepService {
@GET
@Path("sleep")
@Producers(MediaType.APPLICATION_JSON)
public String sleep(@QueryParam("millis") long millis) throws Exception {
Thread.sleep(millis);
return "{ \"millis\": \"" + millis + "\" };
}
}
, .
Helidon MP. , MP MicroProfile. Helidon , , , . , . , , , .
, , — - «hello world» . , curl-.
Curl- JSON, .
, , , — . Thread.dumpStack():
public String sleep(@QueryParam("millis") long millis) throws Exception {
Thread.dumpStack();
Thread.sleep(millis);
return "{ \"millis\": \"" + millis + "\" };
}
. curl, HTTP- , , — millis=100.
curl http://localhost:8081/sleep?millis=100
: , Thread.dumpStack()
.
, : Helidon, Weld, JAX-RS… . , , .
.
invokeAny involeAll , ExecutorService.
import ...
@Path("/")
public class AggregatorServices {
@GET
@Path("anyOf")
@Produces(MediaType.APPLICATION_JSON)
public String anyOf(@QueryParam("left") String left,
@QueryParam("right") String right) throws Exception {
if (left == null || right == null) {
throw new WebApplicationException(Response.Status.BAD_REQUEST);
}
try (var executor = Executors.newVirtualThreadExecutor()) {
Callable<String> task1 = () -> query(left);
Callable<String> task2 = () -> query(right);
// return the first to succeed, cancel the other
return executor.invokeAny(List.of(task1, task2));
}
}
@GET
@Path("allOf")
@Produces(MediaType.APPLICATION_JSON)
public String allOf(@QueryParam("left") String left,
@QueryParam("right") String right) throws Exception {
if (left == null || right == null) {
throw new WebApplicationException(Response.Status.BAD_REQUEST)
}
try (var executor = Executors.newVirtualThreadExecutor()) {
Callable<String> task1 = () -> query(left);
Callable<String> task2 = () -> query(right);
// if one falls, the other is cancelled
return executor.invokeAll(List.of(task1, task2), true)
.stream()
.map(Future::join)
.collect(Collectors.joining(", ", "{", " }"));
}
}
private String query(String endpoint) {...}
}
, AggregatorServices. , : anyOf allOf. anyOf , , .
anyOf. curl-:
curl http://localhost:8081/anyOf?left=/greeting\&right=/sleep?millis=200
localhost:8081 — , — anyOf, — left right. «hello world»:
{"message":"Hello World!"}
, «hello world», 200 . , «hello world» , 200 , «hello world».
1 , , , , .
allOf, :
curl http://localhost:8081/allOf?left=/greeting\&right=/sleep?millis=1
.
{ {"message":"Hello World!"}, { "millis": "1" } }
allOf, .
private String query(String endpoint) {
URI uri = URI.create("http://localhost:8081").resolve(endpoint);
return ClientBuilder.newClient()
.target(uri)
.request(MediaType.APPLICATION_JSON)
.get(String.class);
}
, . API JAX-RS . invokeAll(), .stream (), .map , Collectors.joining(), JSON.
. , invokeAll() — , cancelOnException. , , . , .
Loom. JDK 16, , — JDK 16, , Loom.
.
, , , . , , , .
, . JNI, JNI, Java, Java IO-. , . , .
, , :
, . , , , . , . , .
. , , Java, synchronized wait-notify java.util.concurrent. java.util.concurrent , — ReentrantLock, .
Loom?
Loom , Loom, , .
, , ThreadLocals. ThreadLocals, . . JDK ThreadLocals, .
SimpleDateFormat.
SimpleDateFormat , , ThreadLocals.
JDK SimpleDateFormats java.date dateformatter. ,
static final , . ThreadLocals .
. , . TCP-, . BufferedOutputStream, PrintStream - , . JDK, , .
, , java.util.concurrent .
, .
.
, ,
- . Java ( IntelliJ, NetBeans, Eclipse) JDI, wire protocol, , JVM Tool Interface JVM TI, . , .
, . , .
.
, . : «» ( ) . , . , , . JVM TI .
, , , , .
, : - , , « »? , , . , . , — , - , , .
.
. Java Flight Recorder Loom . , JFR , print JFR, , .
JFR.
server.jfr, . Jetty, . , . . JFR , , 200 , , , .
, . «virtual = true» , . , , , , java.net.url HTTP , 200 . . , JFR, .
Flight Recorder, , , JVM TI, , JVM TI, .
, , .
. , , , . , , , , , . , .
Serviceability
, .
, . , . , , , «» ( CPU), . .
— , . , , ? , ? ? , .
, Loom
, - . , , , .
, . , , .
, , .
API , , API, . API , , , , .
, , , , , , , , IDE , .
Preview: ARM64 Aarch64, 64- Intel ; - .
. « »: , .
, . , .
, CSP Actors. , Erlang . Java , : BlockingQueues, SynchronousQueue, , LinkedTransferQueue, .
, java.util.concurrent, . , . — «conduits», , java.nio.channels. , .
— . -
. . , , , .
Project Loom . , , . , . , , ExecutorService, AutoCloseable, , , , , .
, serviceability observability. , ,
. , - . , , . .
— . , . Java , , . . , - . . , , , , - .
:
— , , , .
— , , , Java.
, , .
, .
, Project Loom, — ( ) . , , . .
: https://jdk.java.net/loom
: loom-dev@openjdk.java.net
-: https://wiki.openjdk.java.net/display/loom/Main
-, — -.
, .
«Safe harbor»: , .
, Java- : Java- , . JPoint, ( , , VMware). , .