Javaのインタビュー、「ロック」がバインドされているときは常にものを挙げることにします。だから、インタビューの中で、私たちは何をすべきかについて話して、あなたが理解するのに十分な「ロック」することを教えているかどうかだろう「ロック」について話しますか?
この記事では、ロックの基本的な原理を分析し、アプリケーションのシナリオをロックすることを目指しています。
一、同期
1、顔の質問
2つの同期方法ライタとオブジェクト内の同じオブジェクトを読者アクセスがA、B二つのスレッドであり、相互に排他的な製造のだろうか?
|
|
答案:会。因为synchronized修饰的是方法,锁是对象锁
,默认当前的对象作为锁的对象。只有当A释放锁之后,B才会获得对象的锁。
(1)如果是换成是不同对象呢?
不会互斥,因为锁的是对象
,而不是方法
。
(2)如果writer、reader方法加上static修饰,两个线程中,类直接调用两个方法呢?
会互斥,因为锁的是Class对象。
(3)如果writer方法用static修饰,reader方法不用呢?
不会互斥。因为一个是对象锁,一个是Class对象锁,锁的类型不同。
synchronized修饰位置与锁的关系:
- 同步方法 —— 对象锁,当前实例对象
- 静态同步方法 —— 类对象锁,当前对象的Class对象
- 同步方法块 —— 对象锁,synchonized括号里配置的对象
二、锁的底层实现
思考几个问题
- 对象锁、Class对象锁时如何实现的
- 为什么要这么设计,只设计一个对象锁或Class对象锁,有什么不好?
1、反编译
|
|
使用javac
和javap -verbose
命令,反编译
上述代码
|
|
同步代码块:使用monitorenter和monitorexit指令实现,通过监听器对象去获得锁
和释放锁
。
同步方法、静态同步方法:使用修饰符ACC_SYNCHRONIZED
实现。
三、锁的形式
JDK1.6前に、唯一の伝統的なロック機構を同期。
偏ったロックロックと軽量:JDK1.6には、ロックの二つの新しいタイプを導入しました。目的には、マルチスレッドの競争、あるいは全く競争例、伝統的なロックによる性能上の問題が存在しない、導入を解決することです。
、何のロック状態を状態、ロック状態軽量、重量級のロック状態をロックする傾向がある:4つの状態がロックしていません。ロックダウングレードではない、アップグレードすることができます。
図1に示すように、オブジェクトヘッド
メカニズムのロックを解除するには、まずオブジェクトヘッダを理解する必要があります。
マークWordのデフォルトのストレージオブジェクトのハッシュコード、年齢や世代ロックフラグのJavaオブジェクトヘッド。
次のようにJavaオブジェクトヘッダ構造を格納することです。
ロック状態 | 25bit | 4ビット | それはバイアスロックであるかどうかを1ビット | 2ビットのロックフラグ |
---|---|---|---|---|
ロックフリー状態 | hashCodeオブジェクト | 対象の世代の年齢 | 0 | 01 |
状態変化のマーク・ワード:
ロック状態 | 30bit | 2ビット |
---|---|---|
軽量ロック | スタックポインタのレコードロックをポインティング | ロックフラグ00 |
ヘビーロック | ポインタのポインティングミューテックス | ロックフラグ10 |
ロック状態 | 23bit | 3ビット | 3ビット | 1ビット | 2ビット |
---|---|---|---|---|---|
バイアスされたロック | スレッドID | 時代 | 世代年齢オブジェクト | 1 | 01 |
図2に示すように、バイアスされたロック
ほとんどの場合、何もロックマルチスレッドの競争、そして同じスレッド数回で得られた合計はありませんので。ロックを獲得するためのコストを下げるために導入されます。
3、軽量ロック
参考資料
オリジナル:ビッグボックス のJavaロックオン