• Home
    • View
    • Login
    This page
    • Normal
    • Export PDF
    • Page Information

    Loading...
  1. Dashboard
  2. Undefined Space
  3. Loom
  4. Getting started

Getting started

  • Created by Alan Bateman, last modified on May 06, 2020

The easiest way to get started is to configure your IDE to use a recent Project Loom Early Access (EA) build and get familiar with using the java.lang.Thread API to create a virtual thread to execute some code. Virtual Threads are just threads that are scheduled by the Java virtual machine rather than the operating system. They are suited to executing code that spends most of its time blocked, maybe waiting for a data to arrive on a network socket. Virtual threads are not suited to running code that is compute bound.

In addition to to the Thread API, the java.util.concurrent.ExecutorService and Executors APIs are have been updated to make it easy to work with virtual threads. Virtual threads are cheap enough that a new virtual thread can be created for each task, no need for pooling of threads.

Thread API

The following uses a static factory method to start a virtual thread. It invokes the join method to wait for the thread to terminate.

Thread thread = Thread.startVirtualThread(() -> System.out.println("Hello"));
thread.join();


The Thread.Builder API can also be used to create virtual threads that are configured at build time. The first snippet below creates an un-started thread. The second snippet creates and starts a thread with name "bob".

Thread thread1 = Thread.builder().virtual().task(() -> System.out.println("Hello")).build();

Thread thread2 = Thread.builder()
                       .virtual()
                       .name("bob")
                       .task(() -> System.out.println("I'm Bob!"))
                       .start();


The Thread.Builder API can also be used to create a ThreadFactory. The ThreadFactory created by the following snippet will create virtual threads named "worker-0", "worker-1", "worker-2", ...

ThreadFactory factory = Thread.builder().virtual().name("worker", 0).factory();


ExecutorService API

The following creates an ExecutorService that runs each task in its own virtual thread. The example uses the try-with-resources construct to ensure that the ExecutorService is shutdown and that the two tasks (each run in its own virtual thread) complete before continuing.

try (ExecutorService executor = Executors.newUnboundedVirtualThreadExecutor()) {
    executor.execute(() -> System.out.println("Hello"));
    executor.execute(() -> System.out.println("Hi"));
}


This example runs three tasks and selects the result of the first task to complete. The remaining tasks are cancelled, which causes the virtual threads running it to be interrupted.

try (ExecutorService executor = Executors.newUnboundedVirtualThreadExecutor()) {
    Callable<String> task1 = () -> "foo";
    Callable<String> task2 = () -> "bar";
    Callable<String> task3 = () -> "baz";
    String result = executor.invokeAny(List.of(task1, task2, task3));
}


This example uses submitTasks to submit three value returning tasks. It uses the CompletableFuture.stream method to obtain a stream that is lazily populated as the tasks complete.

try (ExecutorService executor = Executors.newUnboundedVirtualThreadExecutor()) {
    Callable<String> task1 = () -> "foo";
    Callable<String> task2 = () -> "bar";
    Callable<String> task3 = () -> "baz";
    List<CompletableFuture<String>> cfs = executor.submitTasks(List.of(task1, task2, task3));
    CompletableFuture.stream(cfs)
       .map(CompletableFuture::join)
       .forEach(System.out::println);
}



The following creates an ExecutorService that runs each task in its own virtual thread with a deadline. If the deadline expires before the executor has terminated then the thread executing this code will be interrupted and any tasks running will be cancelled. (which causes the virtual thread to be interrupted).

Instant deadline = Instant.now().plusSeconds(30);
try (ExecutorService executor = Executors.newUnboundedVirtualThreadExecutor().withDeadline(deadline)) {
    :
}


Appendix: Differences between regular Threads and virtual Threads

The following is a list of the subtle differences between the two types of thread:

  1. VirtualThread always report their priority as NORM_PRIORITY. The priority is not inherited and cannot be changed with the setPriority method.
  2. Virtual threads are daemon threads. Their daemon status cannot be changed with the setDaemon method.
  3. Virtual threads cannot be suspend, resumed or stopped with the Thread suspend, resume and stop APIs.
  4. Virtual threads have no permissions when running with a security manager.
  5. Virtual threads are not active threads in their thread group. The getThreadGroup method returns a ThreadGroup that cannot be destroyed and its enumerate methods do not enumerate the virtual threads in the group.


Overview
Content Tools
ThemeBuilder
  • No labels

Terms of Use
• License: GPLv2
• Privacy • Trademarks • Contact Us

Powered by a free Atlassian Confluence Open Source Project License granted to https://www.atlassian.com/software/views/opensource-community-additional-license-offer. Evaluate Confluence today.

  • Kolekti ThemeBuilder Powered by Atlassian Confluence 8.5.23
  • Kolekti ThemeBuilder printed.by.atlassian.confluence
  • Report a bug
  • Atlassian News
Atlassian
Kolekti ThemeBuilder EngineAtlassian Confluence
{"serverDuration": 146, "requestCorrelationId": "a9b7faf918783512"}