理由は、重要なリソースの問題:アクセスに他のスレッドを取るためにリソースへのアクセスのための重要な時期に1つのスレッドではなく、完全に重要なリソースの値を変更するのに十分な時間、重要なリソース、複数のスレッドで結果は同じリソースにアクセスします。直感的な印刷結果が混沌と秩序を示しました。
ソリューション:ロック
非静的な方法によって静的メソッド、オブジェクトのロックを使用してロック。
1.同期コードセグメント:同期(){...}
2.同期方法:修飾同期キーワード使用方法
3.明示的な同期ロックReentrantLockのを
ロック待機状態を説明している外側のロックプール
方法A:同期コードセグメント:同期(){...}
パブリック クラスSourceConflict { 公共 静的 ボイドメイン(文字列[]引数){ // インスタンス化導体4、アナログ導体4 4つのスレッドを持つ RunnableをR&LT =() - > { 一方(TicketCenter.restCount> 0 ){ 同期( "" ){ IF(TicketCenter.restCount <= 0 ){ リターン; } のSystem.out.println(にThread.currentThread()のgetName() + "チケットを購入し、残りの" + --TicketCenter.restCount + "チケット" ); } } }; // アナログ4 4つのスレッドは、導体と 、スレッドスレッド1 = 新しい新しいスレッド(R&LT、「スレッド1」); スレッドスレッド2 = 新しい新しいスレッド(R&LT、「スレッド2」); thread3スレッド = 新しい新しいスレッド(R&LTを、 "スレッド3。" ); thread4スレッド = 新しい新しいスレッド(R&LTを"thread4" ); // オープンスレッド thread1.start(); thread2.start(); thread3.start(); thread4.start() ; } } // 4導体共通チケット、リソース共有、非独立を達成 //ラムダ式匿名の内部又は内部トラッピングローカル変数を明示的に取り込まれ、実用的な効果の最終または最終型として宣言されなければならないか、静的インスタンス変数は、限定されるものではなく、 クラスTicketCenter { パブリック 静的 INT restCount = 100 ; }
方法2:同期修飾法のキーワードを使用して、同期方法、
1 パブリック クラスSourceConflict2 { 2 公共 静的 ボイドメイン(文字列[]引数){ 3 // 4つのスレッドを持つインスタンス化導体4、アナログ導体4 。4 。5 RunnableをR&LT =() - > { 6 ながら(TicketCenter.restCount > 0 ){ 7 sellTicket(); 8 } 9。 }; 10 。11 // 4つのスレッドを持つアナログ導体4 12は スレッドスレッド1 = 新しい新しいスレッド(R&LT、 "スレッド1" )、 13は スレッドスレッド2 = 新しい新スレッド(R、 "スレッド2" )。 14 = thread3スレッド新しいスレッド(Rは、 "thread3" )。 15 = thread4スレッド新しいスレッド(Rは、 "thread4" )。 16 17 // 开启线程 18 thread1.start()。 19 thread2.start()。 20 thread3.start()。 21 thread4.start()。 22 23 } 24 25 プライベート 同期 静的 ボイドsellTicket(){ 26 であれば(TicketCenter.restCount <= 0 ){ 27 リターン; 28 } 29 のSystem.out.println(にThread.currentThread()のgetName()+ + --TicketCenter.restCount + "チケット" "残りのチケットを買う" ); 30 } 31 } 32 33 IS クラスTicketCenter { 34は 公共 静的 INT = 100 restCount ; 35 }
方法3:使用して明示的な同期ロックReentrantLockの
1 インポートjava.util.concurrent.locks.ReentrantLock; 2 。3 パブリック クラスSourceConflict3 { 4 パブリック 静的 ボイドメイン(文字列[]引数){ 5 // 4つのスレッドを持つインスタンス化導体4は、4つの導体アナログ 。6 。7 / / 明示的なロック 。8 = ReentrantLockののロック新しい新しいReentrantLockの()は、 図9 のRunnable R&LT =() - > { 10 ながら(TicketCenter.restCount> 0 ){ 11。 Lock.lock(); 12は IF(TicketCenter.restCount <= 0 ){ 13 リターン; 14 } 15 のSystem.out.println(にThread.currentThread()のgetName()+ + --TicketCenter.restCount + "チケット" "残りのチケットを買う" ); 16 lock.unlock()。 17 } 18 }; 19 20である // 4つのスレッドは、導体とアナログ4 21は スレッドスレッド1 = 新しい新しいスレッド(R&LT、 "スレッド1" )、 22は スレッドスレッド2 = 新しい新しいスレッド(R&LT、 "スレッド2" ;) 23であります =スレッドthread3 新しい新しいスレッド(R&LT、 "thread3" ); 24 = thread4スレッド新しいスレッド(R、 "thread4を" ); 25 26 // 开启线程 27 thread1.start()。 28 thread2.start()。 29 thread3.start()。 30 thread4.start()。 31 32 } 33 }
35クラスTicketCenter {
36のpublic static int型restCount = 100 。
37}