28.12.11

Thread Manager in Java

openjdk.java.net/groups/hotspot/docs/RuntimeOverview.html#VM%20Lifecycle|outline


Thread Management

Thread management covers all aspects of the thread lifecycle, from creation through to termination, and the coordination of threads within the VM. This involves management of threads created from Java code (whether application code or library code), native threads that attach directly to the VM, or internal VM threads created for a range of purposes. While the broader aspects of thread management are platform independent, the details necessarily vary depending on the underlying operating system.

[Notes]
  • Thread types:
    • Threads created from Java Code.
    • Native Threads
    • Internal VM Threads
  • Platform independent vs. platform dependent
    • The details necessarily vary depending on the underlying operating system.


Threading Model

The basic threading model in Hotspot is a 1:1 mapping between Java threads (an instance of java.lang.Thread) and native operating system threads. The native thread is created when the Java thread is started, and is reclaimed once it terminates. The operating system is responsible for scheduling all threads and dispatching to any available CPU.
The relationship between Java thread priorities and operating system thread priorities is a complex one that varies across systems. These details are covered later.

[Notes]
  • 1:1 mapping!!!
  • The operating system is responsible for scheduling all threads and dispatching to any available CPU.


Thread Creation and Destruction

There are two basic ways for a thread to be introduced into the VM: execution of Java code that calls start() on a java.lang.Thread object; or attaching an existing native thread to the VM using JNI. Other threads created by the VM for internal purposes are discussed below.
There are a number of objects associated with a given thread in the VM (remembering that Hotspot is written in the C++ object-oriented programming language):
  • The java.lang.Thread instance that represents a thread in Java code
  • JavaThread instance that represents the java.lang.Thread instance inside the VM. It contains additional information to track the state of the thread. A Java Thread holds a reference to its associated java.lang.Thread object (as an oop), and the java.lang.Thread object also stores a reference to its Java Thread (as a raw int). A JavaThread also holds a reference to its associated OSThread instance.
  • An OSThread instance represents an operating system thread, and contains additional operating-system-level information needed to track thread state. The OSThread then contains a platform specific “handle” to identify the actual thread to the operating system
When a java.lang.Thread is started the VM creates the associated JavaThread and OSThread objects, and ultimately the native thread. After preparing all of the VM state (such as thread-local storage and allocation buffers, synchronization objects and so forth) the native thread is started. The native thread completes initialization and then executes a start-up method that leads to the execution of the java.lang.Thread object's run() method, and then, upon its return, terminates the thread after dealing with any uncaught exceptions, and interacting with the VM to check if termination of this thread requires termination of the whole VM. Thread termination releases all allocated resources, removes the JavaThread from the set of known threads, invokes destructors for the OSThread and JavaThread and ultimately ceases execution when it's initial startup method completes.
A native thread attaches to the VM using the JNI call AttachCurrentThread. In response to this an associated OSThread and JavaThread instance is created and basic initialization is performed. Next a java.lang.Thread object must be created for the attached thread, which is done by reflectively invoking the Java code for the Thread class constructor, based on the arguments supplied when the thread attached. Once attached, a thread can invoke whatever Java code it needs to via the other JNI methods available. Finally when the native thread no longer wishes to be involved with the VM it can call the JNIDetachCurrentThread method to disassociate it from the VM (release resources, drop the reference to the java.lang.Thread instance, destruct the JavaThread and OSThread objects and so forth).
A special case of attaching a native thread is the initial creation of the VM via the JNI CreateJavaVM call, which can be done by a native application or by the launcher (java.c). This causes a range of initialization operations to take place and then acts effectively as if a call to AttachCurrentThread was made. The thread can then invoke Java code as needed, such as reflective invocation of themain method of an application. See the JNI section for further details.

Thread States

The VM uses a number of different internal thread states to characterize what each thread is doing. This is necessary both for coordinating the interactions of threads, and for providing useful debugging information if things go wrong. A thread's state transitions as different actions are performed, and these transition points are used to check that it is appropriate for a thread to proceed with the requested action at that point in time – see the discussion of safepoints below.
The main thread states from the VM perspective are as follows:
  • _thread_new: a new thread in the process of being initialized
  • _thread_in_Java: a thread that is executing Java code
  • _thread_in_vm: a thread that is executing inside the VM
  • _thread_blocked: the thread is blocked for some reason (acquiring a lock, waiting for a condition, sleeping, performing a blocking I/O operation and so forth)
For debugging purposes additional state information is also maintained for reporting by tools, in thread dumps, stack traces etc. This is maintained in the OSThread and some of it has fallen into dis-use, but states reported in thread dumps etc include:
  • MONITOR_WAIT: a thread is waiting to acquire a contended monitor lock
  • CONDVAR_WAIT: a thread is waiting on an internal condition variable used by the VM (not associated with any Java level object)
  • OBJECT_WAIT: a thread is performing an Object.wait() call
Other subsystems and libraries impose their own state information, such as the JVMTI system and the ThreadState exposed by the java.lang.Thread class itself. Such information is generally not accessible to, nor relevant to, the management of threads inside the VM.

Internal VM Threads

People are often surprised to discover that even executing a simple “Hello World” program can result in the creation of a dozen or more threads in the system. These arise from a combination of internal VM threads, and library related threads (such as reference handler and finalizer threads). The main kinds of VM threads are as follows:
  • VM thread: This singleton instance of VMThread is responsible for executing VM operations, which are discussed below
  • Periodic task thread: This singleton instance of WatcherThreadsimulates timer interrupts for executing periodic operations within the VM
  • GC threads: These threads, of different types, support parallel and concurrent garbage collection
  • Compiler threads: These threads perform runtime compilation of bytecode to native code
  • Signal dispatcher thread: This thread waits for process directed signals and dispatches them to a Java level signal handling method
All threads are instances of the Thread class, and all threads that execute Java code are JavaThread instances (a subclass of Thread). The VM keeps track of all threads in a linked-list known as the Threads_list, and which is protected by the Threads_lock – one of the key synchronization locks used within the VM.

No comments: