java代码
setBlocker记录了线程的被哪个对象阻塞,用来给线程监控和分析工具使用
public static void park(Object blocker) {
Thread t = Thread.currentThread();
setBlocker(t, blocker);
UNSAFE.park(false, 0L);
setBlocker(t, null);
}
private static void setBlocker(Thread t, Object arg) {
// Even though volatile, hotspot doesn't need a write barrier here.
UNSAFE.putObject(t, parkBlockerOffset, arg);
}
public static void unpark(Thread thread) {
if (thread != null)
UNSAFE.unpark(thread);
}
C++代码
class Parker : public os::PlatformParker {
private:
volatile int _counter ;
...
public:
void park(bool isAbsolute, jlong time);
void unpark();
...
}
class PlatformParker : public CHeapObj<mtInternal> {
protected:
pthread_mutex_t _mutex [1] ;
pthread_cond_t _cond [1] ;
...
}
1、有两个调用都是在unsafe类(UNSAFE = sun.misc.Unsafe.getUnsafe();),park()和unpark()方法
状态控制
1、通过_counter字段来线程阻塞唤醒进行控制
- 调用park()方法时,会将_counter置为0,同时判断前值,如果小于1,说明之前也是park()状态,继续阻塞(连续unpark()最多为1)
- 调用unpark()方法时,会将_counter置为1,同时判断前值,小于1,说明之前是park()状态,会进行线程唤醒。