Unsafe类park,unpark详解
/**
* Unblock the given thread blocked on <tt>park</tt>, or, if it is
* not blocked, cause the subsequent call to <tt>park</tt> not to
* block. Note: this operation is "unsafe" solely because the
* caller must somehow ensure that the thread has not been
* destroyed. Nothing special is usually required to ensure this
* when called from Java (in which there will ordinarily be a live
* reference to the thread) but this is not nearly-automatically
* so when calling from native code.
* @param thread the thread to unpark.
*
*/
public native void unpark(Object thread);
park方法用于Block current thread。在以下情况下返回
1 针对当前线程已经调用过unpark(多次调用unpark的效果和调用一次unpark的效果一样)
public static void main(String[] args) throws Exception { Unsafe unsafe = UnsafeUtil.getUnsafe(); Thread currThread = Thread.currentThread(); unsafe.unpark(currThread); unsafe.unpark(currThread); unsafe.unpark(currThread); unsafe.park(false, 0); System.out.println("SUCCESS!!!"); }
park方法马上返回
2 在当前线程中断的时候或者调用unpark的时候
public static void main(String[] args) throws Exception { Unsafe unsafe = UnsafeUtil.getUnsafe(); Thread currThread = Thread.currentThread(); new Thread(()->{ try { Thread.sleep(3000); currThread.interrupt(); //unsafe.unpark(currThread); } catch (Exception e) {} }).start(); unsafe.park(false, 0); System.out.println("SUCCESS!!!"); }
park在3秒后返回
3 如果是相对时间也就是isAbsolute为false(注意这里后面的单位纳秒)到期的时候
public static void main(String[] args) throws Exception { Unsafe unsafe = UnsafeUtil.getUnsafe(); //相对时间后面的参数单位是纳秒 unsafe.park(false, 3000000000l); System.out.println("SUCCESS!!!"); }
3秒后 park返回
4 如果是绝对时间也就是isAbsolute为true(注意后面的单位是毫秒)到期的时候
public static void main(String[] args) throws Exception { Unsafe unsafe = UnsafeUtil.getUnsafe(); long time = System.currentTimeMillis()+3000; //绝对时间后面的参数单位是毫秒 unsafe.park(true, time); System.out.println("SUCCESS!!!"); }
3秒后 park返回
5 无理由的返回
unpark方法最好不要在调用park前对当前线程调用unpark
/** * Unblock the given thread blocked on <tt>park</tt>, or, if it is * not blocked, cause the subsequent call to <tt>park</tt> not to * block. Note: this operation is "unsafe" solely because the * caller must somehow ensure that the thread has not been * destroyed. Nothing special is usually required to ensure this * when called from Java (in which there will ordinarily be a live * reference to the thread) but this is not nearly-automatically * so when calling from native code. * @param thread the thread to unpark. * */ public native void unpark(Object thread);