、3つのアプリケーションモードを同期
1、方法の変形例は、オブジェクトの現在のインスタンスは、ロックの現在のインスタンスの前に得られる同期コードで、ロックされています
/ ** *インスタンスメソッドを修正して同期、現在のロック・スレッドは、オブジェクトaccountingSyncのインスタンスである *スレッドがオブジェクトの同期インスタンスメソッドにアクセスして、その後、他の同期方法を他のスレッドがオブジェクトにアクセスすることはできません 一つだけのロックオブジェクト* / * クラスAccountingSync実装Runnableを{公共 静的AccountingSync accountingSync新しい新しいAccountingSync =(); //共有リソース 静的INT I = 0; 静的INT J = 0; 公共ボイド同期増加(){ 私は++; } @Override 公共ボイドRUN(){ 用(;私は1000000 <; I = 0 int型Iが++){ 同期(本){ 増加(); } } } 公共の静的な無効メイン(文字列[]引数)InterruptedExceptionある{スロー スレッドスレッド1 =新しいスレッド(accountingSync)を、 =新しいスレッド(accountingSync)をスレッド2スレッド。 thread1.start(); thread2.start(); thread1.join(); thread2.join(); System.out.println(I); } }
/ ** 同期アクセス方式*スレッド1インスタンスオブジェクトOBJ1、スレッド2 OBJ1オブジェクトのインスタンスは、同期メソッドアクセス オブジェクトロック二つの例は同じではないので、*これは、許可されています。 * 2つのスレッドが非共有のデータを操作する場合は、この時点では、セキュリティスレッドが保証されているデータが共有されている場合は、スレッドセーフを保証することはできません * * / publicクラスが実装Runnableを{AccountingSyncBad 静的int型I = 0; 公共無効同期増加(){ 私は++; } @Override )公共ボイドRUNを({ ため(INT I = 0;私は<1000000; I ++){ 増加(); } } パブリック静的な無効メイン(文字列[]引数)InterruptedExceptionあるが{スロー //新しい新規の新しいインスタンス スレッドスレッド1 =新たにスレッド(新しいAccountingSyncBad()); //新しいの新しい新しいインスタンス スレッドスレッド2 =新しいスレッド(新しいAccountingSyncBad()); thread1.start(); thread2.start(); thread1.join(); thread2.join(); System.out.println(I); } }
2、静的メソッドを変更し、オブジェクトのロックは、現在のクラスオブジェクトを取得するために、ロック同期コードを入力する前に、現在のクラスのクラスであります
クラス実装AccountingSyncClassのRunnable {公共 のint静的I = 0; / ** *同期静的メソッドに作用する、ロック現在のクラスオブジェクト * / パブリック静的ボイド同期増加(){ 私は++; } / ** * increase4Objメソッドがインスタンスメソッドであり、そのオブジェクトロックは、オブジェクトの現在のインスタンスで、 *他のスレッドは、このメソッドは、すべての後に、相互排他、さまざまなロックオブジェクトを生成しません呼び出す場合 、操作の共有(*私たちは、この場合、そのスレッドの安全性の問題を見つけることに注意する必要があり静的変数i)。 * / 公共ボイドは(){同期increase4Obj 私は++; } @Override ます。public void RUN(){ のために(;私は1000000 <; I = 0 int型私は++){ 増加を(); // increase4Obj(); } } 公共の静的な無効メイン(文字列[]引数)が例外:InterruptedExceptionをスロー{ //新しい新实例 スレッドスレッド1 =新しいスレッド(新しいAccountingSyncClass())。 //新しい新实例 スレッドスレッド2 =新しいスレッド(新しいAccountingSyncClass()); thread1.start(); thread2.start(); thread1.join(); thread2.join(); System.out.println(I); } }
図3に示すように、修正されたコードブロック
同期(本)オブジェクトの現在のインスタンスをロックし、
同期(AccountingSync.class)クラスロック対象であります
二、同期コードブロック基本原理
同期コードブロックはmonitorenterとmonitorexit命令の組によって達成される、モニタオブジェクトは、基本的にはユニットを同期化されます。
三、Java仮想マシンは、同期用に最適化されています
1、何の競争がない場合、それがためにデフォルトになりますが発生、ロックをそらします。JVM、WordのスレッドIDの部分を使用して、CAS動作は、マークは、現在のスレッドに向かってオブジェクトを表すためにオブジェクトヘッドに設けられ、それは実際のミューテックスを含みません。そのためには、多くのアプリケーションシナリオでは、オブジェクトのほとんどは競争せずにコストを削減することができ、ロックたわみを使用し、スレッドのロックのライフサイクルまでになるという仮定に基づいています。
別のスレッドが存在する場合2が、競合が発生したときに、すでにロックスキューロックオブジェクトをロックしようとすると、JVMは斜めロックを取り消す取り消し、軽量ロックに切り替わります。軽量ロック依存CAS操作マークWordが成功した場合には、軽量の使用上のロックは、それ以外の場合はヘビー級ではない、ロックを取得しようとするには、ロックをエスカレートし続けます
PS:アイドルMonitorのセーフポイントのセキュリティ・ポイント・チェックにJVM、およびダウングレードしようとするとロックのダウングレードにも、存在します。