スレッドの安全性の問題への最初の解決策:使用してブロックを同期
フォーマット:
同期(ロックオブジェクト){
コードスレッドの安全性の問題が生じる可能性がある(アクセスコードシェアデータ)
}
ブロックは、ロックオブジェクトは、任意のオブジェクトであってもよいが、複数のスレッド間の同一性を確保する必要があります。注意してください
ロックオブジェクトの役割は、スレッド同期コードブロックの実行を行うことができ、同時に、同期ブロックをロックすることです
パッケージcom.fgy.demo02。 / ** *实现卖票案例 * / パブリック クラス RunnableImplの実装のRunnable { プライベート int型のチケット= 100 ; オブジェクトOBJ = 新しいオブジェクト(); @Override 公共 のボイドの実行(){ ながら、(真){ 同期(OBJ){ 場合(チケット> 0 ){ 試み{ のThread.sleep( 100 ); } キャッチ(InterruptedExceptionあるE){ e.printStackTrace(); } のSystem.out.println(にThread.currentThread()のgetName()。 + +チケット+ "チケット" "購入セクションが" ); チケット - ; } } } } }
パッケージcom.fgy.demo02。 パブリック クラスDemo01Ticket { 公共 静的 ボイドメイン(文字列[]引数){ RunnableImpl実行 = 新しいRunnableImpl()。 新しいスレッド(実行).start(); 新しいスレッド(実行).start(); 新しいスレッド(実行).start(); } }
問題の第二のスレッドセーフな解決策:同期方法の使用
これらの手順を実行します。
1.アクセスコードは、プロセス中に、抽出されたデータを共有しました
2.法上の同期修飾子を追加します。
フォーマット:
モディファイ同期戻り値の型メソッド名(...){
コードスレッドの安全性の問題が生じる可能性がある(アクセスコードシェアデータ)
}
ロックオブジェクトの同期方法は次のとおりです。この
静的オブジェクトは、同期方法をロックすることができない、これはオブジェクトを作成した後に生成されるので、オブジェクトに優先して静的メソッドである。この
このクラスのロックオブジェクトの静的メソッドは、クラスファイルの対象となります
パッケージcom.fgy.demo03。 / ** *实现卖票案例 * / パブリック クラス RunnableImplの実装のRunnable { プライベート int型のチケット= 100 ; @Override 公共 のボイドの実行(){ ながら、(真){ payTicket(); } } パブリック 同期 ボイドpayTicket(){ 場合(チケット> 0 ){ 試み{ のThread.sleep( 100 )。 } キャッチ(InterruptedExceptionあるE){ e.printStackTrace(); } のSystem.out.println(にThread.currentThread()のgetName()。 + +チケット+ "チケット" "購入セクションが" ); チケット - ; } } }
スレッドの安全性の問題に第三の選択肢を解決:使用ロックロック
これらの手順を実行します。
ReenterantLock部材の位置にオブジェクトを作成1.
2.コール・ロック・インタフェース・コードは、セキュリティ上の問題(の前に表示される場合があります方法ロック)がロックを取得します
3.コールLockメソッドは、ロックを解除するために)(発生する可能性のあるインターフェイスのセキュリティ問題の後にコードのロックを解除します
パッケージcom.fgy.demo04。 輸入java.util.concurrent.locks.Lock; 輸入java.util.concurrent.locks.ReentrantLock; / ** *实现卖票案例 * / パブリック クラス RunnableImplの実装のRunnable { プライベート int型のチケット= 100 ; ロックリットル = 新しいReentrantLockの(); / * @Override ます。public void実行(){ ながら、(真){ l.lock(); もし(チケット> 0){ 試み{ のThread.sleep(100); }キャッチ(InterruptedExceptionある電子){ e.printStackTrace(); } のSystem.out.println(にThread.currentThread()のgetName()+ "正在买第" +チケット+ "张票"。)。 チケット - ; } l.unlock()。 } } * / @Override 公共 ボイドラン(){ 一方(真){ l.lock()。 もし(チケット> 0 ){ 試み{ のThread.sleep( 100 ); System.out.println(にThread.currentThread()のgetName()。 + "正在买第" +チケット+ "张票" ); チケット - ; } キャッチ(InterruptedExceptionあるE){ e.printStackTrace(); } 最後に{ // 関わらず、ロック異常を解放するプログラムが発生したか否かの l.unlock(); } } } } }