`
lobin
  • 浏览: 433467 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Java/JVM中的各种线程及其继承结构

 
阅读更多

和很多其他编程语言一样,Java也支持多线程。对于不支持多线程的编程语言,在需要并发多任务处理的情况下,就相当困难了,尽管可能有其他的方式来实现。如lua,javascript等。

 

一个支持多线程编程的语言,这里以java为例,java线程和系统线程之间是怎么对应的,参考另一篇有关Java线程模型文章:https://lobin.iteye.com/blog/630684

 

 

Java通过java.lang.Thread描述一个线程。

Java Thread状态定义:

    /**
     * A thread state.  A thread can be in one of the following states:
     * <ul>
     * <li>{@link #NEW}<br>
     *     A thread that has not yet started is in this state.
     *     </li>
     * <li>{@link #RUNNABLE}<br>
     *     A thread executing in the Java virtual machine is in this state.
     *     </li>
     * <li>{@link #BLOCKED}<br>
     *     A thread that is blocked waiting for a monitor lock
     *     is in this state.
     *     </li>
     * <li>{@link #WAITING}<br>
     *     A thread that is waiting indefinitely for another thread to
     *     perform a particular action is in this state.
     *     </li>
     * <li>{@link #TIMED_WAITING}<br>
     *     A thread that is waiting for another thread to perform an action
     *     for up to a specified waiting time is in this state.
     *     </li>
     * <li>{@link #TERMINATED}<br>
     *     A thread that has exited is in this state.
     *     </li>
     * </ul>
     *
     * <p>
     * A thread can be in only one state at a given point in time.
     * These states are virtual machine states which do not reflect
     * any operating system thread states.
     *
     * @since   1.5
     * @see #getState
     */
    public enum State {
        /**
         * Thread state for a thread which has not yet started.
         */
        NEW,

        /**
         * Thread state for a runnable thread.  A thread in the runnable
         * state is executing in the Java virtual machine but it may
         * be waiting for other resources from the operating system
         * such as processor.
         */
        RUNNABLE,

        /**
         * Thread state for a thread blocked waiting for a monitor lock.
         * A thread in the blocked state is waiting for a monitor lock
         * to enter a synchronized block/method or
         * reenter a synchronized block/method after calling
         * {@link Object#wait() Object.wait}.
         */
        BLOCKED,

        /**
         * Thread state for a waiting thread.
         * A thread is in the waiting state due to calling one of the
         * following methods:
         * <ul>
         *   <li>{@link Object#wait() Object.wait} with no timeout</li>
         *   <li>{@link #join() Thread.join} with no timeout</li>
         *   <li>{@link LockSupport#park() LockSupport.park}</li>
         * </ul>
         *
         * <p>A thread in the waiting state is waiting for another thread to
         * perform a particular action.
         *
         * For example, a thread that has called <tt>Object.wait()</tt>
         * on an object is waiting for another thread to call
         * <tt>Object.notify()</tt> or <tt>Object.notifyAll()</tt> on
         * that object. A thread that has called <tt>Thread.join()</tt>
         * is waiting for a specified thread to terminate.
         */
        WAITING,

        /**
         * Thread state for a waiting thread with a specified waiting time.
         * A thread is in the timed waiting state due to calling one of
         * the following methods with a specified positive waiting time:
         * <ul>
         *   <li>{@link #sleep Thread.sleep}</li>
         *   <li>{@link Object#wait(long) Object.wait} with timeout</li>
         *   <li>{@link #join(long) Thread.join} with timeout</li>
         *   <li>{@link LockSupport#parkNanos LockSupport.parkNanos}</li>
         *   <li>{@link LockSupport#parkUntil LockSupport.parkUntil}</li>
         * </ul>
         */
        TIMED_WAITING,

        /**
         * Thread state for a terminated thread.
         * The thread has completed execution.
         */
        TERMINATED;
    }

这些状态在JVM中对应的定义:参考hotspot\src\share\vm\prims\jvm.h中的定义。

/*
 * Java thread state support
 */
enum {
    JAVA_THREAD_STATE_NEW           = 0,
    JAVA_THREAD_STATE_RUNNABLE      = 1,
    JAVA_THREAD_STATE_BLOCKED       = 2,
    JAVA_THREAD_STATE_WAITING       = 3,
    JAVA_THREAD_STATE_TIMED_WAITING = 4,
    JAVA_THREAD_STATE_TERMINATED    = 5,
    JAVA_THREAD_STATE_COUNT         = 6
};

 

Java java.lang.Thread在JVM中java.lang.Thread对象的接口类java_lang_Thread参考hotspot\src\share\vm\classfile\javaClasses.hpp中的代码。

 

java_lang_Thread中的状态定义:

  // Java Thread Status for JVMTI and M&M use.
  // This thread status info is saved in threadStatus field of
  // java.lang.Thread java class.
  enum ThreadStatus {
    NEW                      = 0,
    RUNNABLE                 = JVMTI_THREAD_STATE_ALIVE +          // runnable / running
                               JVMTI_THREAD_STATE_RUNNABLE,
    SLEEPING                 = JVMTI_THREAD_STATE_ALIVE +          // Thread.sleep()
                               JVMTI_THREAD_STATE_WAITING +
                               JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT +
                               JVMTI_THREAD_STATE_SLEEPING,
    IN_OBJECT_WAIT           = JVMTI_THREAD_STATE_ALIVE +          // Object.wait()
                               JVMTI_THREAD_STATE_WAITING +
                               JVMTI_THREAD_STATE_WAITING_INDEFINITELY +
                               JVMTI_THREAD_STATE_IN_OBJECT_WAIT,
    IN_OBJECT_WAIT_TIMED     = JVMTI_THREAD_STATE_ALIVE +          // Object.wait(long)
                               JVMTI_THREAD_STATE_WAITING +
                               JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT +
                               JVMTI_THREAD_STATE_IN_OBJECT_WAIT,
    PARKED                   = JVMTI_THREAD_STATE_ALIVE +          // LockSupport.park()
                               JVMTI_THREAD_STATE_WAITING +
                               JVMTI_THREAD_STATE_WAITING_INDEFINITELY +
                               JVMTI_THREAD_STATE_PARKED,
    PARKED_TIMED             = JVMTI_THREAD_STATE_ALIVE +          // LockSupport.park(long)
                               JVMTI_THREAD_STATE_WAITING +
                               JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT +
                               JVMTI_THREAD_STATE_PARKED,
    BLOCKED_ON_MONITOR_ENTER = JVMTI_THREAD_STATE_ALIVE +          // (re-)entering a synchronization block
                               JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER,
    TERMINATED               = JVMTI_THREAD_STATE_TERMINATED
  };

Java线程对象(java.lang.Thread线程对象)在Java对象内存模型中保存的线程状态就是ThreadStatus中定义的状态。

 

我们在java程序中获取线程状态,得到的Java Thread状态是根据和ThreadStatus对应关系得到的。对应关系如下,以sleep为例,从以下对应关系看出,我们看到的状态是TIMED_WAITING,这里很容易和wait,指定timeout时间时的情况混淆。

 

Java Thread中的状态和java_lang_Thread中的状态对应如下:

const char* java_lang_Thread::thread_status_name(oop java_thread) {
  assert(JDK_Version::is_gte_jdk15x_version() && _thread_status_offset != 0, "Must have thread status");
  ThreadStatus status = (java_lang_Thread::ThreadStatus)java_thread->int_field(_thread_status_offset);
  switch (status) {
    case NEW                      : return "NEW";
    case RUNNABLE                 : return "RUNNABLE";
    case SLEEPING                 : return "TIMED_WAITING (sleeping)";
    case IN_OBJECT_WAIT           : return "WAITING (on object monitor)";
    case IN_OBJECT_WAIT_TIMED     : return "TIMED_WAITING (on object monitor)";
    case PARKED                   : return "WAITING (parking)";
    case PARKED_TIMED             : return "TIMED_WAITING (parking)";
    case BLOCKED_ON_MONITOR_ENTER : return "BLOCKED (on object monitor)";
    case TERMINATED               : return "TERMINATED";
    default                       : return "UNKNOWN";
  };
}

 

 

JVM中的各种线程继承体系

 

JVM中的各种线程

 

 

继承体系

 

 

JVM中OSThread、JavaThread、VMThread、WorkerThread的区别

 

线程函数的定义:

typedef void (*ThreadFunction)(JavaThread*, TRAPS);

 

OSThread

OSThread维护着OS相关的线程信息,它等同于JVM的sys_thread_t结构。

 

OSThread主要的代码在\hotspot\src\share\vm\runtime目录下的osThread.hpp和osThread.cpp

 

OSThread线程相关状态:ALLOCATED、INITIALIZED、RUNNABLE、MONITOR_WAIT、CONDVAR_WAIT、OBJECT_WAIT、BREAKPOINTED、SLEEPING、ZOMBIE。

具体参考ThreadState定义

enum ThreadState {
  ALLOCATED,                    // Memory has been allocated but not initialized
  INITIALIZED,                  // The thread has been initialized but yet started
  RUNNABLE,                     // Has been started and is runnable, but not necessarily running
  MONITOR_WAIT,                 // Waiting on a contended monitor lock
  CONDVAR_WAIT,                 // Waiting on a condition variable
  OBJECT_WAIT,                  // Waiting on an Object.wait() call
  BREAKPOINTED,                 // Suspended at breakpoint
  SLEEPING,                     // Thread.sleep()
  ZOMBIE                        // All done, but not reclaimed yet
};

 

JavaThread

在JVM层面用来描述一个Java线程。Java通过java.lang.Thread来描述一个线程,如以下Java线程代码:

官方的一个例子:

class PrimeThread extends Thread {

long minPrime;

PrimeThread(long minPrime) {

this.minPrime = minPrime;

}

 

public void run() {

// compute primes larger than minPrime

. . .

}

}

启动这个线程也很简单:

Thread t = new PrimeThread();

t.start();

 

JavaThread线程相关状态:参考hotspot\src\share\vm\utilities\globalDefinitions.hpp

enum JavaThreadState {
  _thread_uninitialized     =  0, // should never happen (missing initialization)
  _thread_new               =  2, // just starting up, i.e., in process of being initialized
  _thread_new_trans         =  3, // corresponding transition state (not used, included for completness)
  _thread_in_native         =  4, // running in native code
  _thread_in_native_trans   =  5, // corresponding transition state
  _thread_in_vm             =  6, // running in VM
  _thread_in_vm_trans       =  7, // corresponding transition state
  _thread_in_Java           =  8, // running in Java or in stub code
  _thread_in_Java_trans     =  9, // corresponding transition state (not used, included for completness)
  _thread_blocked           = 10, // blocked in vm
  _thread_blocked_trans     = 11, // corresponding transition state
  _thread_max_state         = 12  // maximum thread state+1 - used for statistics allocation
};

 

Java线程启动执行时,java.lang.Thread中run方法就是线程执行的代码。我们知道,在编写C/C++多线程程序时,在创建一个线程时,会传入一个线程函数。这里java.lang.Thread中run方法就相当于线程函数的实现。Java程序在运行时,JVM中有一个thread_entry函数用于表示Java线程的执行入口run方法。

 

线程函数:

 

static void thread_entry(JavaThread* thread, TRAPS) {
  HandleMark hm(THREAD);
  Handle obj(THREAD, thread->threadObj());
  JavaValue result(T_VOID);
  JavaCalls::call_virtual(&result,
                          obj,
                          KlassHandle(THREAD, SystemDictionary::Thread_klass()),
                          vmSymbols::run_method_name(),
                          vmSymbols::void_method_signature(),
                          THREAD);
}

 

Java线程在启动时, 即调用start方法启动一个java线程,将调用start0方法进行启动,该方法是一个native方法,即进入jvm执行,对应JVM_StartThread函数,在JVM层面,就是通过创建一个JavaThread来启动运行,这个时候会创建一个native thread,即new JavaThread(&thread_entry, sz),其第一个参数为线程函数,第二个参数表示线程对应的栈大小,这里传入的是java.lang.Thread#stackSize的值,但这个值通常为0,所以栈大小取决于vm。

 

其中SystemDictionary::Thread_klass()需要展开宏才能开出来:

static klassOop Thread_klass() { return check_klass_Pre(_well_known_klasses[Thread_klass_knum]); }

 

 

在创建JavaThread时,会调用os::create_thread函数,并传入创建的JavaThread线程对象,以及线程类型ThreadType.java_thread, 以及前面的栈大小,在os::create_thread函数中,会为JavaThread线程分配一个对应的OSThread,再调用pthread_create启动一个线程,在启动这个线程时,传入的线程函数为java_start,线程传入的参数为前面创建的JavaThread线程。

 

pthread_create线程函数:java_start

// Thread start routine for all newly created threads
static void *java_start(Thread *thread) {
  // Try to randomize the cache line index of hot stack frames.
  // This helps when threads of the same stack traces evict each other's
  // cache lines. The threads can be either from the same JVM instance, or
  // from different JVM instances. The benefit is especially true for
  // processors with hyperthreading technology.
  static int counter = 0;
  int pid = os::current_process_id();
  alloca(((pid ^ counter++) & 7) * 128);

  ThreadLocalStorage::set_thread(thread);

  OSThread* osthread = thread->osthread();
  Monitor* sync = osthread->startThread_lock();

  // non floating stack LinuxThreads needs extra check, see above
  if (!_thread_safety_check(thread)) {
    // notify parent thread
    MutexLockerEx ml(sync, Mutex::_no_safepoint_check_flag);
    osthread->set_state(ZOMBIE);
    sync->notify_all();
    return NULL;
  }

  // thread_id is kernel thread id (similar to Solaris LWP id)
  osthread->set_thread_id(os::Linux::gettid());

  if (UseNUMA) {
    int lgrp_id = os::numa_get_group_id();
    if (lgrp_id != -1) {
      thread->set_lgrp_id(lgrp_id);
    }
  }
  // initialize signal mask for this thread
  os::Linux::hotspot_sigmask(thread);

  // initialize floating point control register
  os::Linux::init_thread_fpu_state();

  // handshaking with parent thread
  {
    MutexLockerEx ml(sync, Mutex::_no_safepoint_check_flag);

    // notify parent thread
    osthread->set_state(INITIALIZED);
    sync->notify_all();

    // wait until os::start_thread()
    while (osthread->get_state() == INITIALIZED) {
      sync->wait(Mutex::_no_safepoint_check_flag);
    }
  }

  // call one more level start routine
  thread->run();

  return 0;
}

在java_start线程函数中会调用JavaThread的run方法:

// The first routine called by a new Java thread
void JavaThread::run() {
  // initialize thread-local alloc buffer related fields
  this->initialize_tlab();

  // used to test validitity of stack trace backs
  this->record_base_of_stack_pointer();

  // Record real stack base and size.
  this->record_stack_base_and_size();

  // Initialize thread local storage; set before calling MutexLocker
  this->initialize_thread_local_storage();

  this->create_stack_guard_pages();

  this->cache_global_variables();

  // Thread is now sufficient initialized to be handled by the safepoint code as being
  // in the VM. Change thread state from _thread_new to _thread_in_vm
  ThreadStateTransition::transition_and_fence(this, _thread_new, _thread_in_vm);

  assert(JavaThread::current() == this, "sanity check");
  assert(!Thread::current()->owns_locks(), "sanity check");

  DTRACE_THREAD_PROBE(start, this);

  // This operation might block. We call that after all safepoint checks for a new thread has
  // been completed.
  this->set_active_handles(JNIHandleBlock::allocate_block());

  if (JvmtiExport::should_post_thread_life()) {
    JvmtiExport::post_thread_start(this);
  }

  EVENT_BEGIN(TraceEventThreadStart, event);
  EVENT_COMMIT(event,
     EVENT_SET(event, javalangthread, java_lang_Thread::thread_id(this->threadObj())));

  // We call another function to do the rest so we are sure that the stack addresses used
  // from there will be lower than the stack base just computed
  thread_main_inner();

  // Note, thread is no longer valid at this point!
}

这里最后调用了一个thread_main_inner函数:

void JavaThread::thread_main_inner() {
  assert(JavaThread::current() == this, "sanity check");
  assert(this->threadObj() != NULL, "just checking");

  // Execute thread entry point unless this thread has a pending exception
  // or has been stopped before starting.
  // Note: Due to JVM_StopThread we can have pending exceptions already!
  if (!this->has_pending_exception() &&
      !java_lang_Thread::is_stillborn(this->threadObj())) {
    {
      ResourceMark rm(this);
      this->set_native_thread_name(this->get_thread_name());
    }
    HandleMark hm(this);
    this->entry_point()(this, this);
  }

  DTRACE_THREAD_PROBE(stop, this);

  this->exit(false);
  delete this;
}

其中调用了线程函数:this->entry_point()(this, this);这里的线程函数就是之前创建JavaThread时传入的entry point,即ThreadFunction,也就是调用thread_entry函数。

 

在thread_entry函数中,会调用JavaCalls::call_virtual函数,这之后又回到java,这里后面将执行java程序编译后的字节码,即java.lang.Thread#run()方法编译后的字节码。

 

 

VMThread

VMThread表示原始线程,用于孵化其他所有线程,其他线程也用它来卸载一些VM重操作,如内存清理、垃圾回收等。主要代码在hotspot\src\share\vm\runtime目录下的vmThread.hpp和vmThread.cpp。

 

WorkerThread

 

工作线程,继承至NamedThread,可以指定一个命名标识,以及一个id来标识关联的线程执行的工作。


 

  • 大小: 33.5 KB
分享到:
评论

相关推荐

    java-基础/jvm/多线程

    "Java-基础/jvm/多线程"这个主题涵盖了Java语言的基础知识,包括JVM(Java虚拟机)、多线程以及Java的基础语法和特性。 1. **JVM、JRE和JDK的关系**: - JVM(Java Virtual Machine)是Java程序运行的平台,负责...

    Java面试JVM+多线程重点突破.zip

    Java面试中的JVM(Java虚拟机)和多线程是两个关键的知识领域,对于求职者来说,掌握这两点能够显著提升面试成功率。JVM是Java程序的运行平台,它负责解释执行字节码,实现跨平台运行。多线程则是Java编程中实现并发...

    JAVA核心知识点整理,涵盖JAVA基础、集合类、JVM、IO/NIO、多线程、Spring原理等知识

    本文将根据提供的文件信息,对JAVA基础、集合类、JVM、IO/NIO、多线程以及Spring框架的基本原理进行深入解析,旨在帮助读者全面理解这些核心概念。 #### 1. Java基础 Java语言的基础部分包括了变量、数据类型、...

    java多线程Demo

    在Java中,实现多线程有两种主要方式:继承Thread类和实现Runnable接口。 1. 继承Thread类: 当我们创建一个新的类,让它继承Thread类时,可以通过重写`run()`方法来定义线程执行的任务。然后创建该类的对象,并...

    java进阶提高学习教程-13JVM与多线程.pptx

    Java进阶学习教程中的第13章主要涵盖了JVM(Java虚拟机)和多线程两个核心概念。JVM是Java程序运行的基础,它负责解释执行字节码文件,并提供了Java语言的跨平台特性。Java程序通过JVM与操作系统交互,使得程序可以...

    IO和线程java输入输出 多线程

    Java中的IO(输入/输出)和线程是两个核心概念,它们在开发高效、响应性强的应用程序时起着至关重要的作用。输入/输出处理数据的传输,而多线程则涉及程序的并发执行。 首先,让我们深入理解Java的IO系统。Java.IO...

    Java JVM Instruction Set

    本文档的主要目标是研究Java虚拟机(JVM)的工作原理及其设计背后的原因,而非深入探讨Java语言本身。我们将关注于机器如何运作,并且更重要的是,探究JVM开发者为何选择特定的方式来设计这些功能。 #### 为什么...

    JAVA JVM原理资料

    ### JAVA JVM原理资料知识点 #### 一、语言处理器的基本结构 **语言处理器**是指能够处理某种编程语言的工具,常见的包括编译器、解释器、IDE等。 1. **编译器的基本结构**: - **词法分析器**:将源代码分割成...

    Java并发/多线程

    在Java中,每个Java虚拟机(JVM)实例都有一个主线程,可以通过创建额外的线程来执行并发任务。 2. **线程的创建** - Java提供了多种创建线程的方式,如通过实现Runnable接口或继承Thread类。推荐使用实现...

    Java的多线程(java基础)

    Java的多线程是其编程语言中的一个重要特性,允许在单个程序中同时执行多个任务,从而提高程序的效率和响应性。理解多线程对于Java开发者至关重要,尤其对初学者来说,是掌握高级编程技巧的基础。 首先,我们需要...

    java线程线程安全同步线程

    在Java中,线程的创建可以通过继承`Thread`类或实现`Runnable`接口。线程的主体行为定义在`run()`方法中,当`start()`方法被调用时,线程进入可运行态,系统会根据线程调度策略来决定何时执行线程。线程的状态包括新...

    java 多线程.ppt,多线程

    Java多线程是Java编程中一个重要的概念,它允许程序同时执行多个任务,极大地提高了程序的效率和响应性。在Java中,多线程主要分为两种实现方式:通过子类化Thread类和实现Runnable接口。 1. 子类化Thread类: 当...

    java程序 两个线程实现学生成绩的读写

    在Java中创建线程主要有两种方式:继承`Thread`类或者实现`Runnable`接口。在这个场景下,我们可能创建了两个类,一个是`WriterThread`用于写入成绩,另一个是`ReaderThread`用于读取并显示成绩。 在写入线程(`...

    java线程入门,java线程入门

    Java线程是多任务编程的重要概念,特别是在Java这种支持并发执行的高级编程语言中。Java线程允许程序同时执行多个独立的代码段,这极大地提高了程序的效率和响应性。以下是对Java线程入门的详细讲解: 1. **线程的...

    Java建立一个单线程的实例.rar

    在Java编程语言中,线程是程序执行的基本单元,它允许程序同时执行多个任务。创建一个单线程在Java中非常常见,特别是在处理并发问题时。这个实例将帮助初学者理解如何在Java中创建和管理单线程。下面我们将详细讨论...

    JAVA多线程编程技术PDF

    在Java中,可以通过实现Runnable接口或继承Thread类来创建线程。创建后,调用start()方法启动线程,而非run()方法,因为start()会触发Java虚拟机(JVM)执行线程的run()方法。 其次,线程同步是多线程编程中的关键...

    Java多线程编程模板

    在Java编程中,多线程是程序设计中的一个重要概念,特别是在服务器端应用和高并发场景下,多线程能够充分利用CPU资源,提高程序的执行效率。本知识点将深入探讨Java多线程编程模板,帮助开发者理解和掌握如何在Java...

    Java_多线程与并发编程总结.doc

    Java虚拟机(JVM)为每一个Java应用程序启动一个进程,而在这个进程中,所有的代码执行都是通过线程来完成的。默认情况下,Java程序的main方法在一个称为主线程的线程中运行。当main方法执行完毕,主线程结束,JVM...

    java多线程经典讲义

    在Java中,线程是进程中的一个执行单元,每个进程至少包含一个线程,通常Java虚拟机(JVM)启动时会创建一个进程,即java.exe,其中包含主线程,主要执行main方法。除此之外,还有垃圾回收线程等后台线程在运行。 ...

    jvm特性与java特性

    在深入探讨JVM(Java虚拟机)的特性之前,我们首先需要了解Java虚拟机在整个Java体系中所扮演的角色。Java虚拟机是运行Java字节码的抽象计算机,它使得Java语言具有“一次编写,到处运行”的特性。JVM的特性不但支撑...

Global site tag (gtag.js) - Google Analytics