私たちは、その性能はロック同期ロックを超えてしまった、JDK1.6、完全な最適化を行って同期のためのJava同期ロックの初めから、さらにいくつかのシナリオでは、知っています。だから、私たちはそれが最適化された正確にどのように見てみましょう。
当初発行
Synchronized
ミューテックスのロックを取得し、各操作がもたらすロック解除、達成基礎となるオペレーティングシステムに基づいている用户态
と内核态
切り替え、それによってシステムのパフォーマンスのオーバーヘッドが増加します。
したがって、ロックでの激しい競争の中で、Synchronized
パフォーマンスのパフォーマンスに同期ロックはそれはまた、多くの場合、誰も呼ばれ、非常に悪かったです重量级锁
。
JDK1.5のバージョン、およびsynchronizedキーワード同様の機能との同期を提供してロック機能を実現するロックインタフェースの新しい契約に、しかし、あなたが取得を示し、ロックを解除する必要性を使用する場合。
シングルスレッドの場合、同期はありません、その後で同期ロックロックパフォーマンスJDK1.5のバージョンよりもはるかに優れたパフォーマンス、複数のアプリケーションをロックする可重入锁
機能を。
だから、同期時間は、達成するためにどのように?そして、なぜリエントラントな機能を持っていませんか?
シンクロナイズド原則
同期が入り、チューブ(モニター)オブジェクトの実装を終了するには、JVMに基づいています。各オブジェクトのインスタンスは、モニタオブジェクトが一緒と破壊を作成することができ、モニターを持っています。
複数のスレッドは、同期コードセクションにアクセスすると、複数のスレッドは、最初に記憶されるEntryList集合
(とも呼ばれる阻塞队列
)、及び中BLOCKED
スレッドの状態、それはリストに追加されるであろう。
スレッドが監視する次のオブジェクトを取得すると、ミューテックスロックモニタは、相互に排他的、アプリケーションスレッドのミューテックスの成功を達成するための基盤となるオペレーティングシステムに依存することですミューテックスを保持し、他のスレッドがミューテックスを取得することができなくなります。
スレッドが待機()メソッドを呼び出すと、それが現在開催されたミューテックスを解放し、スレッドが入りますWaitSet集合
(としても知られている等待队列
)、待ち時間が目覚めします。スレッドのこの時点でWAITING
またはTIMEDWAITING
状態、
現在のスレッドが正常にメソッドを実行する場合は、ミューテックスを解放します。
基礎となるオペレーティング・システムは、実装に依存するため、一般に、同期は、この実装でモニタをロックされている、プレゼンス用户态
の内核态
(理解されるように切り替えるには上下文切换
)、パフォーマンス・オーバーヘッドが大きくなります。
ロック・エスカレーション
パフォーマンスを向上させるために、JDK1.6がロック競合によって引き起こされるコンテキストスイッチングを減らすために、軽量で、ヘビー級のロックの概念をロックし、バイアスロックを紹介し、追加されJava对象头
達成するための锁升级
機能を。
いわゆる锁升级
、を指し、
同期した同期ロック当初は
偏向锁
、より競争力のあるスレッドに、偏向锁
にアップグレード轻量级锁
最終的にアップグレードします重量级锁
。
バイアスされたロック
偏向锁
主に今大会のロックと同じスレッドに対して複数のアプリケーションを最適化するために使用されSynchronized锁
、実際にすでにリエントラントロック機能を持っています。
なぜそこにあるべき偏向锁
?スレッドがロックを取得し、ロックを解除するたびに、その後の継続した場合、当社のアプリケーションでは、それは、(そのようなシングルスレッド動作し、スレッドセーフなコンテナなど)同じスレッドのロック競合のリソースのほとんどの時間かもしれないので切り替えます。内核态
用户态
そうで偏向锁
、あるスレッドが再び同期コードまたはメソッドにアクセスするときに、ちょうど現在のスレッドがロックバイアスに保持されているかを決定するためにスレッド対象ヘッダに行きます。
他のスレッドのロック競合のリソースが表示されたら、偏ったロックが取り消されます。バイアスされたロックの失効は、待機する全局安全点
(JVMのstop the world
ロックを保持しているスレッドを中断し、)、およびスレッドはまだメソッドを実行しているかどうかをチェックし、もしそうであれば、逆に他のスレッドによって割り込まれた上で、ロックをアップグレードしてください。
軽量ロック
別のスレッドがロックを獲得競う場合、ロックが既にオブジェクトヘッダーがスレッドIDが自身のスレッドID、CASは、取得が成功した場合、オブジェクトヘッドのための直接交換がロックを獲得するために動作されていないが見出さロックために付勢されていますそのIDのスレッドID、ロックが残る偏向锁
状態、現在のロックを代表して、ロックを取得するために失敗は、いくつかの競争を持っている場合は、バイアスロックにアップグレードされます轻量级锁
。
轻量级锁
適したスレッドが交互シーンシンクブロックを実行し、ロックのほとんどは、もはや全体の同期期間に出場しません。
軽量ロックもサポートされ自旋
、他のスレッドが再び競争ときならば、そう、CAS
失敗し、それはもはや入らないだろう阻塞状态
が、回転し続けます。
以前に言ったので、なぜスピンが良い理由は、デフォルトのスレッドは、スレッドがブロックされている場合は、あまりにも長くはない時間のロックを保持してコストが高くなります停止することができます。
スピンロックの再試行がまだロックをつかむために失敗した後ならば、ロックはアップグレードに同期されます重量级锁
。
ヘビーロック
この状態では、モニターに入ることになるスレッドをつかむなかったロックは、その後にブロックされますWaitSet集合
、それが最適化される前に、ミドルSynchronized锁
。
JVMパラメータ最適化
偏向锁
アップグレードする轻量级锁
時、それはどうなるstop the world
システムは、多くの場合、マルチスレッド化競争であれば、バイアスロックの禁止は、以下を通じて、より良い選択かもしれませんJVM参数
最適化:
// 关闭偏向锁(默认打开)
-XX:-UseBiasedLocking
// 设置重量级锁
-XX:+UseHeavyMonitors
轻量级锁
それは持っている自旋锁
ロック時間を保持しているスレッドが非常に長いので、もし良く、状態をスピンシステムのCPUを占有し、システムのオーバーヘッドが増加するので、スピンロックを最適化するために、この時間を閉じます競争のスレッドでそれほど頻繁に、機能することができます:
-XX:-UseSpinning
概要
上記のJavaで同期ロック用に最適化され、それが再び同期ロックを使用して、このため、最適化の正確JDK1.8後のConcurrentHashMapです。あなたが任意のアイデアを持っている場合は、コメントは以下の歓迎されています。
私のブログをご覧いただくか、私に公共の数、見出し番号を追跡することができます興味を持っている、多分驚きがあるでしょう。