Class VirtualThread

java.lang.Object
com.codename1.backend.VirtualThread

public final class VirtualThread extends Object

A thread of control that is not an OS thread.

One of these per connection is what lets a server keep a context per client without keeping an OS THREAD per client. The difference is not stylistic: a handoff between OS threads measured 21181ns on the machine this was built on, and switching a virtual thread measured 2.6ns.

A virtual thread runs until it finishes or until it asks for bytes that have not arrived, at which point it parks and the host thread goes and runs another one. Parking happens inside the ordinary blocking calls, so the code a virtual thread runs is written in the plain blocking style and does not know it is not a thread -- which is the reason to have them rather than callbacks.

  • Field Summary

    Fields
    Modifier and Type
    Field
    Description
    static final int
    resume(long): the connection is done and the handle should be freed.
    static final int
    resume(long): waiting for bytes; its descriptor goes back to the poller.
    static final int
    resume(long): it gave up its turn but is ready to run again NOW.
  • Method Summary

    Modifier and Type
    Method
    Description
    static long
    create(int fd, int stackBytes)
    A virtual thread that will serve fd when first resumed.
    static int
    descriptorOf(long handle)
    The descriptor this virtual thread serves, or -1.
    static void
    free(long handle)
    Release it.
    static boolean
    Whether the caller is running on a virtual thread rather than a host thread.
    static void
    Print created/finished/freed counts to stderr, for diagnosis.
    static int
    resume(long handle)
    Run it until it parks, yields or finishes.
    static boolean
    Whether this build has virtual threads at all, which is not the same question as isVirtual().
    static void
    Step aside so the host thread can run another virtual thread, without waiting for anything.

    Methods inherited from class Object

    clone, equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Field Details

    • FINISHED

      public static final int FINISHED
      resume(long): the connection is done and the handle should be freed.
      See Also:
    • PARKED_IO

      public static final int PARKED_IO
      resume(long): waiting for bytes; its descriptor goes back to the poller.
      See Also:
    • RUNNABLE

      public static final int RUNNABLE

      resume(long): it gave up its turn but is ready to run again NOW.

      It is waiting on something that is not its socket -- the collector's allocation backpressure, or its own fairness yield. Putting it on the poller instead would wait for a client that is waiting for the response this virtual thread owes it, and the connection would hang for ever.

      See Also:
  • Method Details

    • create

      public static long create(int fd, int stackBytes)

      A virtual thread that will serve fd when first resumed.

      The stack is the C stack only. Java locals and the operand stack live in the virtual thread's own VM state, which is mapped lazily, so what this size buys is call DEPTH rather than data: it holds the C activation records of the Java methods the connection is nested inside.

      Returns:
      a handle, or 0 if the stack could not be allocated
    • resume

      public static int resume(long handle)
      Run it until it parks, yields or finishes. One of the three constants.
    • descriptorOf

      public static int descriptorOf(long handle)
      The descriptor this virtual thread serves, or -1.
    • free

      public static void free(long handle)
      Release it. Only valid once resume(long) has returned FINISHED.
    • yieldNow

      public static void yieldNow()

      Step aside so the host thread can run another virtual thread, without waiting for anything.

      Parking happens by itself when bytes have not arrived. This is for the other case: a virtual thread that COULD keep going but has had its turn. A no-op when the caller is not a virtual thread.

    • isVirtual

      public static boolean isVirtual()
      Whether the caller is running on a virtual thread rather than a host thread.
    • supported

      public static boolean supported()
      Whether this build has virtual threads at all, which is not the same question as isVirtual(). The context switch is compiled in only on non-Windows aarch64/x86_64; elsewhere create() can only ever return 0. The server asks this to pick its default poll mode.
    • report

      public static void report()
      Print created/finished/freed counts to stderr, for diagnosis.