Javaでの最適化の原則を同期します

私たちは、その性能はロック同期ロックを超えてしまった、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です。あなたが任意のアイデアを持っている場合は、コメントは以下の歓迎されています。

私のブログをご覧いただくか、私に公共の数、見出し番号を追跡することができます興味を持っている、多分驚きがあるでしょう。

https://death00.github.io/

おすすめ

転載: www.cnblogs.com/death00/p/11617721.html