How the main thread is created in Java

To create a thread in Java you create a Thread object and call its start method. This raises the question, how is the very first thread of an application started? If it’s created calling the start method, which thread calls it?

The apparent chicken-or-egg problem is easily solved: From a lower level perspective, a Thread object is a mere representation of a thread in a program; it is not a thread itself. That is, a Thread object does not maintain the information about call stacks and program counters that a thread should maintain; it only serves as storage for a pointer to lower level mechanisms that implement threads. This means that the JVM is capable of creating threads without using the Thread class, and the Thread object can be created later if needed.

If we study the source code of application startup in OpenJDK 7 we can see how exactly the Thread object is created for the main thread in the Hotspot JVM. In src/share/vm/runtime/Threads.cpp we find a lot of threading related code, the most interesting one being the Threads::create_vm C++ function. This function called directly from the java application launcher (and the CreateJavaVM function in JNI), and it is running in a thread that was created by the operating system when it started the process. It is a very long function, responsible for setting up the JVM so that a Java application can be run. In this function we find this code:

// Attach the main thread to this os thread
JavaThread* main_thread = new JavaThread();

The C++ JavaThread class is used for bookkeeping inside Hotspot; it associates an low level thread with a Java Thread object. The Java object doesn’t exist yet; it is created much later, and at this point the main_thread object will only hold information about the native main thread. The code then goes on to initialize various other things, and later on still in the same function we find this:

// Initialize java_lang.System (needed before creating the thread)
if (InitializeJavaLangSystem) {
  initialize_class(vmSymbols::java_lang_System(), CHECK_0);
  initialize_class(vmSymbols::java_lang_ThreadGroup(), CHECK_0);
  Handle thread_group = create_initial_thread_group(CHECK_0);
  initialize_class(vmSymbols::java_lang_Thread(), CHECK_0);
  oop thread_object = create_initial_thread(thread_group, main_thread, CHECK_0);
  // Set thread status to running since main thread has
  // been started and running.

In other words, we initialize the System, ThreadGroup, and Thread classes, and call create_initial_thread to create a Java Thread object. Then we sets the Thread object for main_thread.

You may be wondering what create_initial_thread does. It allocates memory for the Java Thread object, storing a pointer to the C++ JavaThread object in its private eetop field. Then it sets the thread priority field to normal, calls the Thread(ThreadGroup group,String name) constructor, and returns the instance. Here it is in all its glory:

// Creates the initial Thread
static oop create_initial_thread(Handle thread_group, JavaThread* thread, TRAPS) {
  klassOop k = SystemDictionary::resolve_or_fail(vmSymbols::java_lang_Thread(), true, CHECK_NULL);
  instanceKlassHandle klass (THREAD, k);
  instanceHandle thread_oop = klass->allocate_instance_handle(CHECK_NULL);

  java_lang_Thread::set_thread(thread_oop(), thread);
  java_lang_Thread::set_priority(thread_oop(), NormPriority);

  Handle string = java_lang_String::create_from_str("main", CHECK_NULL);

  JavaValue result(T_VOID);
  JavaCalls::call_special(&result, thread_oop,
  return thread_oop();

After Threads::create_vm returns the Thread object for the main thread has been created, and the JVM is now ready to start to execute Java code.