public static void main(String[] args) throws Exception { Thread thread = new Thread(() -> { System.out.println("开始睡眠..."); // 开始睡眠 LockSupport.park(); System.out.println("已被唤醒!"); }); thread.start(); Thread.sleep(1000); System.out.println("睡了1秒钟之后开始唤醒..."); // 开始唤醒 LockSupport.unpark(thread); }
输出:
开始睡眠... 睡了1秒钟之后开始唤醒... 已被唤醒!
从示例中,我们大概就能明白park和unpark方法的作用,park方法类似于wait,unpark方法类似于notify。下面我们再看一下复杂一点的示例,来深刻理解park和unpark方法的作用。
public static void park() { UNSAFE.park(false, 0L); } // ... public static void unpark(Thread thread) { if (thread != null) UNSAFE.unpark(thread); }
public native void park(boolean isAbsolute, long time); public native void unpark(Object var1);
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] ; ... }
可以看到Parker类实际上用Posix的mutex(),condition来实现的。mutex是操作系统函数,Synchronized底层也是调用mutex互斥锁的。
void Parker::park(bool isAbsolute, jlong time) { // Ideally we‘d do something useful while spinning, such // as calling unpackTime(). // Optional fast-path check: // Return immediately if a permit is available. // We depend on Atomic::xchg() having full barrier semantics // since we are doing a lock-free update to _counter. if (Atomic::xchg(0, &_counter) > 0) return;
ThreadBlockInVM tbivm(jt); if (_counter > 0) { // no wait needed _counter = 0; status = pthread_mutex_unlock(_mutex);
if (time == 0) { status = pthread_cond_wait (_cond, _mutex) ; } _counter = 0 ; status = pthread_mutex_unlock(_mutex) ; assert_status(status == 0, status, "invariant") ; OrderAccess::fence();
void Parker::unpark() { int s, status ; status = pthread_mutex_lock(_mutex); assert (status == 0, "invariant") ; s = _counter; _counter = 1; if (s < 1) { if (WorkAroundNPTLTimedWaitHang) { status = pthread_cond_signal (_cond) ; assert (status == 0, "invariant") ; status = pthread_mutex_unlock(_mutex); assert (status == 0, "invariant") ; } else { status = pthread_mutex_unlock(_mutex); assert (status == 0, "invariant") ; status = pthread_cond_signal (_cond) ; assert (status == 0, "invariant") ; } } else { pthread_mutex_unlock(_mutex); assert (status == 0, "invariant") ; } }
原文:https://www.cnblogs.com/caoxb/p/13139616.html