JUCソース分析5-locks-LockSupport
LockSupportはunsafeを通じてスレッドをブロックし、起動する方法を提供し、AQSや他のlockはこのベースクラスに使用されます.
各スレッドにはvolatile Object parkBlockerがあります.フィールドは、ブロックを設定するときにそのスレッドにブロックされ、スレッドを監視するために使用できます.LockSupportでは、parkBlockerの設定と取得方法も提供されています.
LockSupportは、最下位のunsafeを介してpark,unpark操作を提供する.簡単に言えば、下位層は二義性を維持しています.
_counterはライセンスを保存します.このライセンスは使い捨てであることに注意してください.unpark操作は値を1に設定し、park操作は値が1であるかどうかをチェックします.1は直接戻り、1でないとブロックされます.
次の状況を考慮します.
1.unpark->park、unparkは許可を解放し、parkは直接戻り、ブロックしない.
2.unpark->park->park、unparkは1つの許可を解放し、2回のparkブロック;
3.park->unpark->unpark、parkブロック後に何度もunpark、unpark修正_counterは1で、複数回呼び出しても構わないが、なぜこれを単独で提案したのかは、AQS共有モードでロックを取得した後、ロック待ちのスレッドをすべて通知し、ブロックキューからヘッダノードを削除/起動してforループを使用するため、複数回unpark操作が可能であると感じたからである(個人的な考えでは、必ずしも完全に正確ではなく、誰が理解しているか説明できる).
wait/notifyを使用して同期を実現すると、notifyがwaitの前に実行され、waitがブロックされ続け、問題が発生します.
blockerパラメータとblockerパラメータを持たない:
LockSupportのjavadoc説明は3の場合すぐに戻ります.
1.他のスレッドが本スレッドのunpark操作を呼び出した.
2.他のスレッドが本スレッドを中断
3.The call spuriously (that is, for no reason) returns.
上記の3つのケースを除いて、下層Unsafeのpublic native void park(boolean flag,long l);次の場合も起動します.
1.flagはtrueで、転送されたdeallineは
2.flagはfalseで、入力したpark時間timeは着きました
unpark操作が起動すると、スレッドスケジューリングは各プラットフォームによって自分で制御されます.
参照先:
http://blog.csdn.net/hengyunabc/article/details/28126139
http://www.360doc.com/content/14/0812/22/1073512_401408738.shtml
private LockSupport() {} // Cannot be instantiated.
private static final Unsafe unsafe = Unsafe.getUnsafe();
private static final long parkBlockerOffset;
static {
try {
parkBlockerOffset = unsafe.objectFieldOffset
(java.lang.Thread.class.getDeclaredField("parkBlocker"));
} catch (Exception ex) { throw new Error(ex); }
}
各スレッドにはvolatile Object parkBlockerがあります.フィールドは、ブロックを設定するときにそのスレッドにブロックされ、スレッドを監視するために使用できます.LockSupportでは、parkBlockerの設定と取得方法も提供されています.
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 Object getBlocker(Thread t) {
if (t == null)
throw new NullPointerException();
return unsafe.getObjectVolatile(t, parkBlockerOffset);
}
LockSupportは、最下位のunsafeを介してpark,unpark操作を提供する.簡単に言えば、下位層は二義性を維持しています.
_counterはライセンスを保存します.このライセンスは使い捨てであることに注意してください.unpark操作は値を1に設定し、park操作は値が1であるかどうかをチェックします.1は直接戻り、1でないとブロックされます.
次の状況を考慮します.
1.unpark->park、unparkは許可を解放し、parkは直接戻り、ブロックしない.
2.unpark->park->park、unparkは1つの許可を解放し、2回のparkブロック;
3.park->unpark->unpark、parkブロック後に何度もunpark、unpark修正_counterは1で、複数回呼び出しても構わないが、なぜこれを単独で提案したのかは、AQS共有モードでロックを取得した後、ロック待ちのスレッドをすべて通知し、ブロックキューからヘッダノードを削除/起動してforループを使用するため、複数回unpark操作が可能であると感じたからである(個人的な考えでは、必ずしも完全に正確ではなく、誰が理解しているか説明できる).
wait/notifyを使用して同期を実現すると、notifyがwaitの前に実行され、waitがブロックされ続け、問題が発生します.
blockerパラメータとblockerパラメータを持たない:
public static void park(Object blocker) {
Thread t = Thread.currentThread();
setBlocker(t, blocker);
unsafe.park(false, 0L);
setBlocker(t, null);
}
public static void parkNanos(Object blocker, long nanos) {
if (nanos > 0) {
Thread t = Thread.currentThread();
setBlocker(t, blocker);
unsafe.park(false, nanos);
setBlocker(t, null);
}
}
public static void parkUntil(Object blocker, long deadline) {
Thread t = Thread.currentThread();
setBlocker(t, blocker);
unsafe.park(true, deadline);
setBlocker(t, null);
}
public static void park() {
unsafe.park(false, 0L);
}
public static void parkNanos(long nanos) {
if (nanos > 0)
unsafe.park(false, nanos);
}
public static void parkUntil(long deadline) {
unsafe.park(true, deadline);
}
LockSupportのjavadoc説明は3の場合すぐに戻ります.
1.他のスレッドが本スレッドのunpark操作を呼び出した.
2.他のスレッドが本スレッドを中断
3.The call spuriously (that is, for no reason) returns.
上記の3つのケースを除いて、下層Unsafeのpublic native void park(boolean flag,long l);次の場合も起動します.
1.flagはtrueで、転送されたdeallineは
2.flagはfalseで、入力したpark時間timeは着きました
unpark操作が起動すると、スレッドスケジューリングは各プラットフォームによって自分で制御されます.
<span style="font-size:18px;">public static void unpark(Thread thread) {
if (thread != null)
unsafe.unpark(thread);
}</span>
参照先:
http://blog.csdn.net/hengyunabc/article/details/28126139
http://www.360doc.com/content/14/0812/22/1073512_401408738.shtml