一、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
---------------------