Hotspot Thread本地方法实现 源码解析

本文详细解析了Java线程API的本地方法实现,包括start, join, sleep, interrupt/interrupted, yield, holdsLock和setPriority。深入探讨了这些方法如何与操作系统线程交互,例如创建线程、等待线程结束、线程休眠、中断和优先级设置等。" 105175799,9423182,Android绘图:使用TextPaint绘制文字,"['Android开发', 'Java', 'UI绘制']
摘要由CSDN通过智能技术生成

   目录

1、start

2、join

3、sleep

4、interrupt / interrupted

5、yeild

6、holdsLock

7、setPriority


     Java中操作线程都是通过Thread的API来实现,其中核心逻辑都封装在本地方法中,其实现在jdk\src\share\native\java\lang\Thread.c中,部分方法如将当前线程置为悬浮状态的suspend,从悬浮状态恢复正常执行的resume方法和停止线程执行的stop方法都被标记成过时方法,本篇博客就不关注了,重点探讨其他的常用方法的实现细节。

1、start

     start方法用于创建一个关联的本地线程并启动该线程的执行,其实现如下:

public synchronized void start() {
        //0表示状态是NEW,如果不是0则抛出异常
        if (threadStatus != 0)
            throw new IllegalThreadStateException();

        //通知所属的ThreadGroup该线程启动执行了,ThreadGroup本身维护了已启动线程的数组和计数
        group.add(this);

        boolean started = false;
        try {
            start0();
            started = true;
        } finally {
            try {
                if (!started) {
                    //增加未启动线程计数,将其从已启动数组中移除
                    group.threadStartFailed(this);
                }
            } catch (Throwable ignore) {
               //启动失败本身会抛出异常给调用方
            }
        }
    }

void add(Thread t) {
        synchronized (this) {
            if (destroyed) {
                throw new IllegalThreadStateException();
            }
            //threads是一个数组,维护所有已启动的线程
            if (threads == null) {
                threads = new Thread[4];
            } else if (nthreads == threads.length) {
                //如果threads满了,则扩容一倍
                threads = Arrays.copyOf(threads, nthreads * 2);
            }
            //保存t
            threads[nthreads] = t;
            //已启动线程数加1
            nthreads++;
            //未启动线程数减1,执行Thread的构造方法时会将该计数加1
            nUnstartedThreads--;
        }
    }

 void threadStartFailed(Thread t) {
        synchronized(this) {
            //从threads数组中移除
            remove(t);
            //未启动线程数加1
            nUnstartedThreads++;
        }
    }

private void remove(Thread t) {
        synchronized (this) {
            if (destroyed) {
                return;
            }
            for (int i = 0 ; i < nthreads ; i++) {
                if (threads[i] == t) {
                    //将i以后的数组元素整体往前挪一位
                    System.arraycopy(threads, i + 1, threads, i, --nthreads - i);
                    //nthreads对应的数组元素置为NULL
                    threads[nthreads] = null;
                    break;
                }
            }
        }
    }

start0就是一个本地方法,会给当前Thread实例创建一个C++ JavaThread实例和OSThread实例,前者是线程在JVM中的表示,后者表示底层操作系统的原生线程,这三个都是一对一关系,Thread实例和JavaThread,JavaThread和OSThread都保存了彼此的引用。创建并初始化完成后,会设置OSThread的优先级,栈帧大小等属性,然后启动OSThread执行JavaThread的run方法,该方法会执行Thread实例的run方法。注意如果重复调用start方法或者因为内存不足导致OSThread创建失败都会抛出异常,其实现如下:

JVM_ENTRY(void, JVM_StartThread(JNIEnv* env, jobject jthread))
  JVMWrapper("JVM_StartThread");
  JavaThread *native_thread = NULL;
  bool throw_illegal_thread_state = false;

  {
    //获取锁
    MutexLocker mu(Threads_lock);

    if (java_lang_Thread::thread(JNIHandles::resolve_non_null(jthread)) != NULL) {
      //如果关联的JavaThread不为空,说明该线程已经启动过,需要抛出异常
      throw_illegal_thread_state = true;
    } else {
      //获取stackSize属性,1.4以上不是从Thread实例中读取,直接返回0
      jlong size =
             java_lang_Thread::stackSize(JNIHandles::resolve_non_null(jthread));
      
      size_t sz = size > 0 ? (size_t) size : 0;
      //创建JavaThread和关联的OSThread
      native_thread = new JavaThread(&thread_entry, sz);

      if (native_thread->osthread() != NULL) {
        //osthread不为空,prepare方法会建立Java Thread实例同JavaThread之间的关联关系
        //并将Java线程的优先级映射成原生线程的优先级并设置
        native_thread->prepare(jthread);
      }
    }
  }

  if (throw_illegal_thread_state) {
    //关联的JavaThread不为空,抛出异常
    THROW(vmSymbols::java_lang_IllegalThreadStateException());
  }

  assert(native_thread != NULL, "Starting null thread?");

  if (native_thread->osthread() == NULL) {
    //创建osthread失败,抛出异常
    delete native_thread;
    if (JvmtiExport::should_post_resource_exhausted()) {
      JvmtiExport::post_resource_exhausted(
        JVMTI_RESOURCE_EXHAUSTED_OOM_ERROR | JVMTI_RESOURCE_EXHAUSTED_THREADS,
        "unable to create new native thread");
    }
    THROW_MSG(vmSymbols::java_lang_OutOfMemoryError(),
              "unable to create new native thread");
  }
  
  //启动线程开始执行
  Thread::start(native_thread);

JVM_END

//获取eetop属性,该属性是一个long类型,保存关联的JavaThread指针
JavaThread* java_lang_Thread::thread(oop java_thread) {
  return (JavaThread*)java_thread->address_field(_eetop_offset);
}

jlong java_lang_Thread::stackSize(oop java_thread) {
  //获取stackSize属性
  if (_stackSize_offset > 0) {
    //只有1.4才会读取
    assert(JDK_Version::is_gte_jdk14x_version(), "sanity check");
    return java_thread->long_field(_stackSize_offset);
  } else {
    return 0;
  }
}

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


JavaThread::JavaThread(ThreadFunction entry_point, size_t stack_sz) :
  Thread() //Thread的构造方法就是初始化Thread的各属性
{
  if (TraceThreadEvents) {
    tty->print_cr("creating thread %p", this);
  }
  //初始化JavaThread自有的各种属性
  initialize();
  _jni_attach_state = _not_attaching_via_jni;
  //entry_point就是执行的run方法
  set_entry_point(entry_point);
  os::ThreadType thr_type = os::java_thread;
  //是否编译线程,编译线程也是JavaThread,但是对应的os::ThreadType类型不同
  thr_type = entry_point == &compiler_thread_entry ? os::compiler_thread :
                                                     os::java_thread;
  //创建一个原生线程,底层通过pthread_create创建,创建成功后将其设置到Thread的_osthread属性中,然后等待其初始化完成
  //,初始化结束后在startThread_lock上等待被唤醒
  //如果内存不足导致创建失败,则该属性为NULL
  os::create_thread(this, thr_type, stack_sz);
}

//prio默认是NoPriority
void JavaThread::prepare(jobject jni_thread, ThreadPriority prio) {

  assert(Threads_lock->owner() == Thread::current(), "must have threads lock");
  
  Handle thread_oop(Thread::current(),
                    JNIHandles::resolve_non_null(jni_thread));
  assert(InstanceKlass::cast(thread_oop->klass())->is_linked(),
    "must be initialized");
  //保存关联的Java Th
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值