Java线程优先级深入jvm理解

一、java中线程优先级定义

public
class Thread implements Runnable {
    ...
    private int            priority;
    ...
    /**
     * The minimum priority that a thread can have.
     */
    public final static int MIN_PRIORITY = 1;

   /**
     * The default priority that is assigned to a thread.
     */
    public final static int NORM_PRIORITY = 5;

    /**
     * The maximum priority that a thread can have.
     */
    public final static int MAX_PRIORITY = 10;
    ...
    private void init(ThreadGroup g, Runnable target, String name,
                      long stackSize, AccessControlContext acc) {
    
    ...
    Thread parent = currentThread();
    ...
    this.priority = parent.getPriority();
    ...
    }
    ...
    public final void setPriority(int newPriority) {
        ThreadGroup g;
        checkAccess();
        if (newPriority > MAX_PRIORITY || newPriority < MIN_PRIORITY) {
            throw new IllegalArgumentException();
        }
        if((g = getThreadGroup()) != null) {
            if (newPriority > g.getMaxPriority()) {
                newPriority = g.getMaxPriority();
            }
            setPriority0(priority = newPriority);
        }
    }
    ...
    private native void setPriority0(int newPriority);
    ...
}

1、最小线程优先级是1,最大线程优先级10,默认是5;

2、创建线程时默认使用当前线程的优先级,也可以通过setPriority设置线程优先级;

3、设置线程优先级的时候会调用native方法,具体实现在jvm中;

二、jvm中线程优先级的定义

os.hpp

jvm中线程类型枚举

  enum ThreadType {
    vm_thread,
    cgc_thread,        // Concurrent GC thread
    pgc_thread,        // Parallel GC thread
    java_thread,
    compiler_thread,
    watcher_thread,
    os_thread
  };

 jvm中线程优先级枚举

enum ThreadPriority {        // JLS 20.20.1-3
  NoPriority       = -1,     // Initial non-priority value
  MinPriority      =  1,     // Minimum priority
  NormPriority     =  5,     // Normal (non-daemon) priority
  NearMaxPriority  =  9,     // High priority, used for VMThread
  MaxPriority      = 10,     // Highest priority, used for WatcherThread
                             // ensures that VMThread doesn't starve profiler
  CriticalPriority = 11      // Critical thread priority
};

  NoPriority       = -1,     // 初始值
  MinPriority      =  1,     // 最小优先级
  NormPriority     =  5,     // 一般优先级(非deamon线程)
  NearMaxPriority  =  9,     // 高优先级,用于VMThread
  MaxPriority      = 10,     // 高优先级,用于WatcherThread
                             // ensures that VMThread doesn't starve profiler
  CriticalPriority = 11      // Critical thread priority

setPriority0的jvm实现

Java 层声明的本地方法对应实现在 Thread.c 中,setPriority0是一个注册到 JVM 中的方法,它与 JVM 中的JVM_SetThreadPriority函数绑定了,所以实现逻辑在JVM_SetThreadPriority函数里。逻辑为: 
* JVMWrapper("JVM_SetThreadPriority")用于调试。 
* 通过 MutexLocker 获取互斥锁。 
* 转成 JVM 层使用的 oop 对象,它是 JVM 中对 Java 层 Thread 对象的描述。 
* 设置 oop 对象的优先级属性值,这里通过java_lang_Thread::set_priority来设置,即java_thread->int_field_put(_priority_offset, priority),这里是通过计算 oop 对象中 priority 属性存储的偏移地址,然后将值设置到该地址。 
* 通过java_lang_Thread::thread获取 JavaThread 指针,即(JavaThread*)java_thread->address_field(_eetop_offset),其中通过计算 eetop 偏移来获取,eetop 属于 Java 层的 Thread 类中的属性。可以这样做的原因是 JavaThread 对象维护了一个指向 oop 的指针,而 oop 也同样维护了一个指向 JavaThread 对象的指针。 
* 最后调用Thread::set_priority来设置操作系统级别的线程优先级,通过调用os::set_priority来实现。

static JNINativeMethod methods[] = {
    ...
    {"setPriority0",     "(I)V",       (void *)&JVM_SetThreadPriority},
    ...
};

JVM_ENTRY(void, JVM_SetThreadPriority(JNIEnv* env, jobject jthread, jint prio))
  JVMWrapper("JVM_SetThreadPriority");
  MutexLocker ml(Threads_lock);
  oop java_thread = JNIHandles::resolve_non_null(jthread);
  java_lang_Thread::set_priority(java_thread, (ThreadPriority)prio);
  JavaThread* thr = java_lang_Thread::thread(java_thread);
  if (thr != NULL) {                  
    Thread::set_priority(thr, (ThreadPriority)prio);
  }
JVM_END

void Thread::set_priority(Thread* thread, ThreadPriority priority) {
  debug_only(check_for_dangling_thread_pointer(thread);)
  (void)os::set_priority(thread, priority);
}

接着看os::set_priority函数的实现: 
* 首先判断优先级值的合法性。 
* 其次是通过java_to_os_priority将 Java 层的优先级映射成操作系统的优先级,各种操作系统不相同,在下面“优先级映射”中细讲。 
* 最后将调用set_native_priority函数设置线程优先级,各种操作系统不相同。

OSReturn os::set_priority(Thread* thread, ThreadPriority p) {
  if (p >= MinPriority && p <= MaxPriority) {
    int priority = java_to_os_priority[p];
    return set_native_priority(thread, priority);
  } else {
    assert(false, "Should not happen");
    return OS_ERR;
  }
}

对于Linux

调用系统函数setpriority来实现,成功返回 OS_OK。

OSReturn os::set_native_priority(Thread* thread, int newpri) {
  if (!UseThreadPriorities || ThreadPriorityPolicy == 0) return OS_OK;

  int ret = setpriority(PRIO_PROCESS, thread->osthread()->thread_id(), newpri);
  return (ret == 0) ? OS_OK : OS_ERR;
}

对于Windows

调用系统函数SetThreadPriority来实现,成功返回 OS_OK。

OSReturn os::set_native_priority(Thread* thread, int priority) {
  if (!UseThreadPriorities) return OS_OK;
  bool ret = SetThreadPriority(thread->osthread()->thread_handle(), priority) != 0;
  return ret ? OS_OK : OS_ERR;
}

三、优先级映射

对于Linux

Java 层的1,10分别对应 Linux 的4和-5,Linux 线程的优先级值范围是 -20到19,其中-20位最高优先级,19位最低优先级,Java 则是使用了-5到4来映射1到10的优先级。

int os::java_to_os_priority[CriticalPriority + 1] = {
  19,              // 0 Entry should never be used

   4,              // 1 MinPriority
   3,              // 2
   2,              // 3

   1,              // 4
   0,              // 5 NormPriority
  -1,              // 6

  -2,              // 7
  -3,              // 8
  -4,              // 9 NearMaxPriority

  -5,              // 10 MaxPriority

  -5               // 11 CriticalPriority
};

对于Windows

Java 层的1和2都映射到THREAD_PRIORITY_LOWEST,其他也类似,连续两个值分别映射到相同值上。

int os::java_to_os_priority[CriticalPriority + 1] = {
  THREAD_PRIORITY_IDLE,                         // 0  Entry should never be used
  THREAD_PRIORITY_LOWEST,                       // 1  MinPriority
  THREAD_PRIORITY_LOWEST,                       // 2
  THREAD_PRIORITY_BELOW_NORMAL,                 // 3
  THREAD_PRIORITY_BELOW_NORMAL,                 // 4
  THREAD_PRIORITY_NORMAL,                       // 5  NormPriority
  THREAD_PRIORITY_NORMAL,                       // 6
  THREAD_PRIORITY_ABOVE_NORMAL,                 // 7
  THREAD_PRIORITY_ABOVE_NORMAL,                 // 8
  THREAD_PRIORITY_HIGHEST,                      // 9  NearMaxPriority
  THREAD_PRIORITY_HIGHEST,                      // 10 MaxPriority
  THREAD_PRIORITY_HIGHEST                       // 11 CriticalPriority
};

而 Windows 平台有如下值,可以看到并没有对全部值进行映射。

THREAD_MODE_BACKGROUND_BEGIN
THREAD_MODE_BACKGROUND_END
THREAD_PRIORITY_ABOVE_NORMAL
THREAD_PRIORITY_BELOW_NORMAL
THREAD_PRIORITY_HIGHEST
THREAD_PRIORITY_IDLE
THREAD_PRIORITY_LOWEST
THREAD_PRIORITY_NORMAL
THREAD_PRIORITY_TIME_CRITICAL
--------------------- 


 

参考:从Java到JVM到OS线程的优先级

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值