テキスト形式のボーエンの始まり:(2点)
プロジェクト |
コンテンツ |
「オブジェクト指向プログラミング(Javaの)」 |
https://home.cnblogs.com/u/nwnu-daizh/ |
どこの仕事でこの要件 |
https://www.cnblogs.com/nwnu-daizh/p/12073034.html |
ジョブの学習目標 |
(1)プロパティと優先スケジューリング方法スレッドを理解し、マスター; (2)スレッド同期技術の概念と実装を把握します。 (3)Javaのスレッド包括的なプログラミング演習 |
エッセイボーエン本文の内容は次のとおりです。
前編:スレッド同期技術の概要(10分)
スレッド同期
マルチスレッドの不確実性のソリューションを同時に実行:別のスレッドがこの方法を使用するように、スレッド同期メカニズムの導入、あなただけ待つことができます。
Javaでソリューションマルチスレッドの同期、2があります。
1.-のJava SE 5.0 ReentrantLockのは、クラスを導入しました。
2.-同期修飾子は、共有メモリに基づく方法の前に添加しました。
......
公共同期の静的な無効サブ(int型メートル)
......
解決策1:ロックオブジェクトおよび条件オブジェクト
以下と保護ReentrantLockのコードブロックの基本構造:
myLock.lock();
{試します
危険域
} 最後に{
myLock.unlock(); }
ロックオブジェクトおよび条件オブジェクトに関するキーポイント:
1、いつでも唯一のスレッドが保護でコードを実行していることを確実にするために、ロック・コード・セグメントを保護します。
2、ロックマネージャのスレッドが保護コードセグメントを入力しようとしています。
図3に示すように、ロックは、オブジェクトに関連する1つ以上の条件を有することができます。
図4に示すように、保護されたコードセグメントに入ったが、実行できない各条件オブジェクト管理スレッド。
対処方法2:synchronizedキーワード
synchronizedキーワードの役割:
図1に示すように、同期方式と呼ばれる特定のクラス同期改質方法、後。
2は、限り、スレッドが同期メソッドにアクセスして、他のスレッドが同期メソッドにアクセスしたいとプリアンブルメソッドが返すからスレッドがブロックされたスレッドを覚ますまで、他のスレッドの当事者が同期方法を入力することがブロックされます。
このスレッドが待機できるようにする3、スレッド同期方法が使用された場合、それが必要な問題かもしれ、あなたが待機を使用する必要があります()メソッド一時的にCPUを使用する権利を放棄し、他のスレッドがこの同期方法を使用することができます。
4.あなたがスレッド同期方法が不足した場合に起因終わりを待っている待機中のスレッドで、このメソッドを使用するのnotifyAll()メソッドを通知に、すべての同期を実行する必要があります。
オブジェクトのロック
(1)同期処理(ロック現在のオブジェクト)
(2)コードの同期ブロック(オブジェクトのロック用)
これ:同期コード・ブロックをロックするオブジェクトを設定するために使用されなければならない場合は、現在のオブジェクトをロックすることが一般的に可能です。
(3)同期マルチオブジェクトロック
複数のオブジェクトは、同期ロック動作を同期させることができない場合、ロックはそれによって同期化され得ることができるように、ロックオブジェクトのロックキーではなく、コードの一部またはメソッド(関数)を取得しました。
グローバルロック
グローバルロックを達成するための2つの方法があります。
(1)同期静的メソッドで使用されるキーワード
同期静的メソッドは、静的な型クラスに適用される、ロックされた同期および非静的なアプローチは、オブジェクトのロックに適用されます。すべてのオブジェクトクラスのインスタンス機能のためのクラスロック月。
(2)クラスのクラスと同期オブジェクトをロックします
静的メソッド同期同じ効果を有するコードブロックの同期(クラス)に作用します。
マルチスレッドアクセスは、8つのメソッドを同期:
A:2つのスレッドが同時に、オブジェクトの同期方法、同期実行にアクセスします。
II:2つのスレッドが並列に、同期方法を2つのオブジェクトをアクセスします。
3:2つのスレッドが同時に同期静的メソッド、同期実行にアクセスします。
4:2つのスレッドが同時にアクセスし、同期および非同期メソッドmethod、同時実行。
5:2つの異なるスレッドが同じオブジェクト、同期実行にアクセス同期方法。
6:2つのスレッドが静的同期方法および非静的同期方法、並列実行にアクセスします。
7:メソッドが例外をスローし、それがロックを解除します。
八:一般的な方法で呼び出し同期方法は、スレッドセーフではないで、同期範囲のみ役割を「{}」内の、
パートII:実験の部
実験1:試験手順1(5分)
同期パッケージ変更のため、 java.utilのインポートクラス* ;. インポートjava.util.concurrent.locks * ;. / ** 銀行口座がロックシリアル化アクセス@versionを使用して、多くの銀行がある1.30 2004-08-01 * * @authorケイHorstmann * / publicクラス銀行 { 民間最終ダブル[]アカウント、 プライベートロックbankLock; 条件条件sufficientFundsプライベート; / ** *建設銀行。 * @Param Nアカウント * @param initialBalance各アカウントの初期バランス * / パブリック・バンク(N-INT、ダブルinitialBalance) { 新しい新しいダブル= [N-]アカウント、 Arrays.fill(アカウント、initialBalance)を、 ReentrantLockののbankLockは新しい新=() ; sufficientFunds bankLock.newCondition(= ); //待機状態の前に、ロックが現在のスレッドによって保持されなければなりません。 } / ** * 1つの口座から別のお金。 * @Paramは、口座振替から * @paramがアカウントに転送する * @paramは私があなたに伝えるために許可する * / 公共のボイド転送(にint型からint型、ダブル量)がスローInterruptedExceptionある { bankLock.lock(); //ロック 試行 対象条件に{//ロックオブジェクト参照 しながら(アカウント【から<AMOUNT) sufficientFunds.await()を; //割り込み信号を受信する前に、現在のスレッドを引き起こすか、待機状態にありました。 System.out.printの(にThread.currentThread()); アカウント[から] - = AMOUNT; System.out.printf( "%10.2f%DからDへ%"、AMOUNT、へ、から) アカウント[します] + =量。 System.out.printf( "トータルバランス:%N-%10.2f"、getTotalBalance()); } sufficientFunds.signalAll();すべてのスレッドがこの状態で待機している場合//すべてのスレッドウェイクアップ } 最後に { bankLock.unlockを(); //アンロック。 } } / ** *すべての口座残高の合計を取得します。 * @Returnトータルバランス * / パブリックダブルgetTotalBalance() { bankLock.lock(); 試み { ダブルSUM = 0; (ダブルA:アカウント)が 、SUM = A + 戻りSUM; } 最後に { bankLock.unlock()。 *銀行での口座の数を取得します。 * @Returnアカウント } / ** * / パブリックINTサイズ() { 戻りaccounts.length。 } }
;用のSynch Package変更 / ** 安全に複数のスレッドがデータ構造にアクセスする方法*このプログラムを示しています。 2015年6月21日@Version 1.31 * * @authorケイHorstmann * / publicクラスSynchBankTest { NACCOUNTSファイナル= 100 INTのpublic static; パブリック静的ダブル最終INITIAL_BALANCE = 1000; パブリック静的ダブル最終MAX_AMOUNT = 1000; DELAY =最終int型のpublic static 10; 公共の静的な無効メイン(文字列[] args) { 銀行銀行=新しい新しい銀行(NACCOUNTS、INITIAL_BALANCE); のため(INT I = 0; I <NACCOUNTS; I ++) { int型fromAccount = I; RunnableをR&LT =() - > { 試み { (trueに)しばらく { のInt toAccount =(INT)(bank.size()* Math.random()); ダブルMAX_AMOUNT AMOUNT * = Math.random(); bank.transfer(fromAccount、toAccount、AMOUNT) のThread.sleep((INT) (DELAY * Math.random())) ; // スリープ状態に現在実行中のスレッドで指定されたミリ秒数を作る } } キャッチ(InterruptedExceptionあるE) { } }; スレッドスレッド新しい新しいT =(R&LT); t.start( ); //スレッドが実行を開始します } } }
結果は以下の通りであります:
ロックオブジェクトおよび条件オブジェクトに関するキーポイント:
1、いつでも唯一のスレッドが保護でコードを実行していることを確実にするために、ロック・コード・セグメントを保護します。
2、ロックマネージャのスレッドが保護コードセグメントを入力しようとしています。
図3に示すように、ロックは、オブジェクトに関連する1つ以上の条件を有することができます。
図4に示すように、保護されたコードセグメントに入ったが、実行できない各条件オブジェクト管理スレッド。
実験1:試験手順2(5分)
用synch2パッケージ変更; java.utilのインポートクラスは* ;. / ** *銀行は、同期プリミティブを複数持っている銀行口座の使用。 2004-08-01 @version 1.30 * * @authorケイHorstmann * / publicクラス銀行 { 民間最終ダブル[]アカウント; / ** *建設銀行。 * @Param Nアカウント * @param initialBalance各アカウントの初期バランス * / パブリック・バンク(N-INT、ダブルinitialBalanceは) { ;新しい新しいダブル= [N-]アカウント Arrays.fill(アカウント、initialBalanceを); } / ** *一方の口座から別のお金。 口座振替から* @Param *アカウントに転送する@param * @param私があなたに伝えるために許可します * / 同期のボイド公共の転送(にint型からint型を、ダブル量)はInterruptedExceptionあるスロー { (<金額[から]アカウント)しばらく 待ち(); //は集中を待つスレッドを追加 System.out.print(にThread.currentThread() ); アカウント[から] - = AMOUNT; System.out.printf( "%10.2f%DからD%まで"、AMOUNT)へ、から、 アカウント[に対する] + = AMOUNT; System.out.printf( "バランス合計:N-%10.2f%」、getTotalBalance()); のnotifyAll(); //現在のスレッドがブロックさ和らげる } / ** *は、すべての口座残高の合計を取得します。 * @Returnトータルバランス * / パブリックダブルgetTotalBalance同期() { ダブルSUM = 0。 (ダブルA:アカウント)について 、SUM = A + リターンSUM; } / ** *銀行口座の番号を取得します。 @return * * / パブリックINTサイズ() { 戻りaccounts.length; } }
synch2パッケージ変更のための; / ** * *このプログラムは、データ構造体への安全なアクセスのために複数のスレッド同期メソッドを使用する方法を示します。 2015年6月21日@Version 1.31 * * @authorケイHorstmann * / publicクラスSynchBankTest2 { NACCOUNTSファイナル= 100 INTのpublic static; パブリック静的ダブル最終INITIAL_BALANCE = 1000; パブリック静的ダブル最終MAX_AMOUNT = 1000; DELAY =最終int型のpublic static 10; 公共の静的な無効メイン(文字列[] args) { 銀行銀行=新しい新しい銀行(NACCOUNTS、INITIAL_BALANCE) ため(INT Iは= 0; I <NACCOUNTS; I ++) { int型fromAccount = I; //内部クラスが使用される のRunnableを= R&LT() - > { トライ { 一方(真の) { int型toAccount =(INT)(bank.size()* Math.random()); //うちランダムアカウント 二量= MAX_AMOUNT * Math.random() ; // ランダムに設定マネー bank.transfer(fromAccount、toAccount、量) ; // 転送動作 のThread.sleep((int型)(DELAY * Math.random())); // ランダムな睡眠時間 } } キャッチ(InterruptedExceptionあるE)//スロー異常 { } }; スレッドスレッド新しい新しいT =(R&LT); t.start(); } } }
結果は以下の通りであります:
マルチスレッドアクセスは、8つのメソッドを同期:
A:2つのスレッドが同時に、オブジェクトの同期方法、同期実行にアクセスします。
II:2つのスレッドが並列に、同期方法を2つのオブジェクトをアクセスします。
3:2つのスレッドが同時に同期静的メソッド、同期実行にアクセスします。
4:2つのスレッドが同時にアクセスし、同期および非同期メソッドmethod、同時実行。
5:2つの異なるスレッドが同じオブジェクト、同期実行にアクセス同期方法。
6:2つのスレッドが静的同期方法および非静的同期方法、並列実行にアクセスします。
7:メソッドが例外をスローし、それがロックを解除します。
八:一般的な方法で呼び出し同期方法は、スレッドセーフではないで、同期範囲のみ役割を「{}」内の、
実験1:試験手順3(5分)
クラスCbank { プライベート静的int型S = 2000; パブリック静的ボイドサブ(INT M) { int型の一時= S。 TEMP = TEMP-M。 {試す のThread.sleep((int型)(1000年* Math.random())); } キャッチ(InterruptedExceptionある電子){} 、S = TEMP。 System.out.println( "S =" + S)。 } } クラスの顧客は、スレッド延び { 公共ボイドラン() { 用(INTを私= 1; I <= 4; I ++) Cbank.sub(100)。 } } publicクラスThread3 { 公共の静的な無効メイン(文字列引数[]) { カスタマーcustomer1 =新しいCustomer(); カスタマーcustomer2 =新しいCustomer(); customer1.start(); customer2.start(); } }
結果は以下の通りであります:
次のように改良されたコードです。
クラスCbank { プライベート静的int型S = 2000; パブリック同期静的ボイドサブ(int型M) { int型温度= S。 TEMP = TEMP-M。 {試す のThread.sleep((int型)(1000年* Math.random())); } キャッチ(InterruptedExceptionある電子){} 、S = TEMP。 System.out.println( "S =" + S)。 } } クラスの顧客は、スレッド延び { 公共ボイドラン() { 用(INTを私= 1; I <= 4; I ++) Cbank.sub(100)。 } } publicクラスThread3 { 公共の静的な無効メイン(文字列引数[]) { 顧客customer1 =新規顧客(); カスタマーcustomer2 =新しいCustomer(); customer1.start(); customer2.start(); } }
結果は以下の通りであります:
2実験:ペアプログラミングの練習は、次の4つの部分をカバーして(10分)
ツイニングパートナー:李華
プログラミングのアイデアの1)の説明。
プログラムの設計の主なアイデアは、あまりにもスレッドクラスとオープンスレッド内のスレッドを作成し、わずか3つの新しいチケットのブースに複雑ではありませんし、その後、ねじタスクで定義されたrunメソッドでは、例外処理の設計は、チケット状況は10票以内で掲載します、プログラムが終了する10人の以上の票を印刷します。
2)プログラミング仕様のプログラムコードに沿って、
package math; public class Demo { public static void main(String[] args) { Mythread mythread = new Mythread(); Thread ticket1 = new Thread(mythread); Thread ticket2 = new Thread(mythread); Thread ticket3 = new Thread(mythread);//新建三个Thread类对象 ticket1.start(); ticket2.start(); ticket3.start();//调用thread类的start方法来开启线程
} } class Mythread implements Runnable {//实现runnable接口进行线程的创建 int ticket = 1; boolean flag = true; @Override public void run() {//将线程任务代码定义到run方法中 while (flag) { try { Thread.sleep(500); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } synchronized (this) { if (ticket <= 10) { System.out.println(Thread.currentThread().getName() + "窗口售:第" + ticket + "张票"); ticket++;//票数在10张之内时,进行打印直到售出10张票时停止 } if (ticket > 10) { flag = false; } } } } }
3) 程序运行功能界面截图;
实验总结:(5分)
在本周的学习中,我学习了线程同步这一知识点,我了解到这一知识点是用来解决多线程并发运行不确定性问题。学习了解决多线程同步问题的两种方案,分别是锁对象与条件对象引用和 synchronized关键字。在实验课上收获了当注释调代码sufficientFunds.await();会出现死锁状态等知识,感受颇多。注意点有:线程如果用完同步方法,应当执行notifyAll()方 法通知所有由于使用这个同步方法而处于等待的 线程结束等待。线程如果用完同步方法,应当执行notifyAll()方 法通知所有由于使用这个同步方法而处于等待的 线程结束等待。以后会坚持学习Java。