方法内の1変数は、スレッドセーフな、非スレッドセーフインスタンス変数であります
変数のメソッドは常にスレッドセーフ、非スレッド安全性の問題が存在しません。これは、変数がプライベートプロパティが引き起こされる内部メソッドです。
複数のスレッドが共通のオブジェクトのインスタンス変数にアクセスする場合、それは「非スレッドセーフ」の問題に可能です。
オブジェクトの前記複数の複数ロック
我々は、キーワードロック作ら同期されるオブジェクトのロック他のスレッド、スレッド、メソッドのロックは、オブジェクトに属する保持同期キーワードと方法を実行するためにどのスレッド、ロックとしてではなく、コードまたはメソッド(関数)の一部を唯一の待機状態で、複数のスレッドが同じオブジェクトにアクセスすることを条件とします。複数のスレッドが複数のオブジェクトにアクセスする場合は、JVMは、複数のロックを作成します。
複数のスレッドがオブジェクトにアクセスする - 「オブジェクトのロックを作成します
複数のスレッドが複数のオブジェクトにアクセスする - 「複数のオブジェクトのロックを作成します
3.synchronized方法およびロックオブジェクト
1)最初のスレッドは、ロックオブジェクトがロックオブジェクト、Bスレッドができ保持非同期オブジェクトにオブジェクトを呼び出す非同期型。
2)スレッドは、第一の目的は、ロックロック、呼び出し元のスレッドが同期され、あなたが待機する必要があり、この時、でObject型のオブジェクトを同期している場合はBメソッドは、オブジェクトを保持します。
4.synchronizedロックリエントラント
キーワードは、同期使用するときは、スレッドがオブジェクトのロックを取得するときに、ロックが再び要求されたこのオブジェクトが再びロックの対象とすることができ、ある再入可能ロック機能を有する同期。
「リエントラントロック」の概念がある:彼らは再び自分自身の内部ロックを取得することができます。たとえば、オブジェクトのロックを獲得するスレッドがあり、そのオブジェクトのロックが解除されていませんあなたはこのオブジェクトのロックを取得したい場合は、再度、まだ中に取得することができ、ないリエントラントロック場合、それは死を引き起こしますロック。
1つの パブリック クラスサービス{ 2 同期 公共 ボイドService1の(){ 3 のSystem.out.println( "サービス1" )。 4 サービス2()。 5 } 6 同期 公共 ボイドサービス2(){ 7 のSystem.out.println( "サービス2" )。 8 service3()。 9 } 10 同期 公共 ボイドservice3(){ 11 のSystem.out.println( "service3" )。 12 } 13 }
1つの パブリック クラス MyThreadが延びスレッド{ 2 3 公共 静的 ボイドメイン(文字列[]引数){ 4 (新MyThread())(開始)。 5 } 6 7 @Override 8 公共 ボイドラン(){ 9 スーパー.RUN()。 10 Serviceサービス= 新しいサービス(); 11 service.service1(); 12 13 } 14 }
5. Syncは、継承を持っていません
同期は継承を持っていないので、私は、サブクラスのメソッドにsynchronizedキーワードを追加する必要があります
6.synchronized同期ブロック
スレッドがタスクを実行するために長い時間同期メソッドを呼び出すなどのいくつかのケースでは、キーワードsynchronized文と1)の方法は、欠点があり、その後、Bは比較的長い時間を待つ必要がありますスレッド。synchronized文は、この場合に使用することができるシンクブロックが解決されます。
2)(本)同期ブロック同期同じオブジェクトにアクセスするには、2つの並行スレッドが実行される時間だけスレッド、コードを実行する他のスレッドを待機する現在のスレッドがこのブロックの終了後に実行された場合ブロック。
3)同期していないブロックを非同期的に実行され、同期は、同期ブロックで行われます。
4)と同期方法として、同期(これは)現在のオブジェクトのロックブロックです。
7.同期方法及び同期コードブロック
複数のスレッドは、同期メソッドを同期または同期同じオブジェクトの異なる名前を呼び出すときに効果と呼ばれる(本)同期ブロックは、順次実行即ち同期、ブロックされています。
1.synchronized同期方法
1)ブロックされた状態のような他のシンクブロック同期または同期同期方式(詳細)を呼び出します。
2)一つだけスレッドがコード同期同期方法を実行することができます。
(本)同期ブロック同期2.
1)ブロックされた状態のような他のシンクブロック同期または同期同期方式(詳細)を呼び出します。
2)一つだけスレッドが同期ブロック内の(この)同期コードを実行することができます。
対象となる任意のオブジェクトの8モニター
Javaはまた、同期機能を実現するために「オブジェクト・モニター」として「任意のオブジェクト」をサポートしています。この「任意のオブジェクト」のほとんどはインスタンス変数とのメソッドのパラメータを(この非オブジェクト)同期フォーマットを使用して、。
前提1)同じオブジェクトのスレッド「オブジェクトモニター」を複数保持し、唯一のスレッドが同期ブロックに(非このオブジェクトX)同期コードを実行することができると同時に。
2)同じオブジェクトの保持前提「オブジェクトモニター」、同時に一つだけスレッドが同期ブロック内(非このオブジェクトX)同期コードを実行することができる場合。
利点:;、しかし、あなたは、この非同期ブロックのロックオブジェクトを使用する場合、時間を同期させることができますが、ブロックされることになるので、パフォーマンスに影響を与えるものの、クラスの数は、同期方法に存在する場合
(非本)同期プログラムコードブロックの同期方法は、非同期であり、このロックは、他のロックと、この同期方法を競合しないだろう、非常に作業効率を向上させることができます。
同期動作は、「同期(非このオブジェクトX)同期コード・ブロック」形式を使用する場合、モニターは、同じオブジェクトを受けなければなりません。それは同じオブジェクトのモニターではない場合、実行結果は、非同期呼び出しで、それが実行交差します。
1 パブリック クラスUserServiceの{ 2 プライベート文字列のユーザ名。 3 プライベート文字列のパスワード。 4 プライベート文字列str = 新しい文字列(); 5 公共 無効セット(文字列名、文字列のパスワード){ 6 7 同期(文字列){ 8 試し{ 9 のSystem.out.println(にThread.currentThread()のgetName()+ ":開始:" + のSystem.currentTimeMillis() ); 10 この .username = ユーザ名; 11 のThread.sleep(3000 ); 12 のSystem.out.println(にThread.currentThread()のgetName()+ ":終了:" + のSystem.currentTimeMillis())。 13 14 } キャッチ(InterruptedExceptionある電子){ 15 e.printStackTrace(); 16 } 17 } 18 } 19 }
1つの パブリック クラススレッドAが延びスレッド{ 2 プライベートUserServiceのUserServiceのを、 3 4 公共スレッドA(UserServiceのUserServiceの){ 5 本 .userService = UserServiceの。 6 } 7 8 @Override 9 公共 ボイドラン(){ 10 userService.set( ""、 "AA" )。 11 } 12 } 13の 14 15 パブリック クラス ThreadBは延びスレッド{ 16は 民間UserServiceのUserServiceの; 17 18 公共ThreadB(UserServiceのUserServiceの){ 19 この .userService = UserServiceの。 20 } 21 22 @Override 23 公共 ボイドラン(){ 24 userService.set( "B"、 "BB" )。 25 } 26 }
1 パブリック クラスを実行{ 2 公共 静的 ボイドメイン(文字列[]引数){ 3 4 UserServiceのUserServiceの= 新しいUserServiceの()。 5 スレッドA A = 新しいスレッドA(UserServiceの)。 6 a.setName( "A" )。 7 a.start()。 8 ThreadB B = 新しいThreadB(UserServiceの)。 9 b.setName( "B" )。 10 b.start()。 11 } 12 }
セットのstr方法でオブジェクトを作成するためのコードの変更UserService.java。同期コードブロックの非同期実行、2つのスレッドが同じオブジェクトのロックに得られないからです。
1 パブリック クラスUserServiceの{ 2 プライベート文字列のユーザ名。 3 プライベート文字列のパスワード。 4 5 公共の ボイド集合(文字列名、文字列のパスワード){ 6 文字列str = 新しい文字列()。 7 同期(STR){ 8 試み{ 9 のSystem.out.println(にThread.currentThread()のgetName()+ ":開始:" + のSystem.currentTimeMillis())。 10 この .username = ユーザ名; 11 のThread.sleep(3000 ); 12 System.out.println(にThread.currentThread()のgetName()+ ":終了:" +。のSystem.currentTimeMillis())。 13 14 } キャッチ(InterruptedExceptionある電子){ 15 e.printStackTrace(); 16 } 17 } 18 } 19 }