要約:
1.シングルスレッド環境場合、データ依存性は、共有変数を操作するためのいくつかの方法が存在して、マルチスレッド環境は、それらが動作しなければならないこと原子の基であり、変数を共有すべての変更の排他的です。これらの操作は、共有変数の相互に排他的及びアトミックない読み出し動作を行う方法、そのようなコピーオンライトモードとして、設計を見るために読み出されたプログラム排他必要があるかどうかは、読み取り効率を向上させることができるが、欠点は、読み出し動作が読み込まれるたびに保証されていません最新の値です。
2.マルチスレッドタスクの正確さを保証するために、それを保証するアクセス共有変数への各スレッドの正当性に基づいています。
3.また、データ依存性や制御方法は、マルチスレッド環境用の他のスレッドの他のスレッドの視認性と秩序操作の操作結果の存在に依存していることを保証しなければなりません。起こる-前原理はこの二点に基づいています。
4.データ依存シングルスレッドケースの不在に特に注意が、関連する動きを実行する他のスレッド。何のデータ依存シングルスレッドが存在しないため、コンパイラは、アウトオブオーダー実行を可能性が高いです。そのような共有変数を変更し、他のスレッドが目を覚ますように、2つの動きの下ねじ方法注文実行はシングルスレッドで結果に影響を及ぼさないであろう、データの存在に依存しません。しかし、マルチスレッド環境、共有変数の値に応じて作業するために必要とされ得る覚醒するスレッドは、これらの2つのアクションは、マルチスレッド環境における実際のデータの存在に依存しています。
質問は、マルチスレッドを使用することは非常にシンプルであり、億数を求めています。この記事では、マルチスレッドプログラミングの考え方をまとめたマルチスレッドタスクの正確さを保証するためにある、共有変数への各スレッドベースのセキュリティアクセスが保証されます。
共有データを定義します。
パブリック クラスArraySource { // ソースアレイ プライベート INT []ソース; // 積算結果 プライベート int型の結果= 0 ; // 現在動作するスレッドの数 プライベート INT threadNumを、 ArraySource(INT []ソース、INT threadNum){ この .SOURCE = 光源と、 この .threadNum = threadNum; } 公共 のint []メソッドgetSource(){ 戻り 、この.SOURCEを; } 公共 のintgetResult(){ 戻り 、この.resultと、 } 公共 ボイド setResult(int型の結果){ この .result = 結果。 } 公共 INT getThreadNum(){ 戻り 、この.threadNumと、 } 公共 ボイド setThreadNum(INT threadNum){ この .threadNum = threadNum。 } }
スレッドのタスクを定義します。
パブリック クラス SumThreadは拡張スレッド{ プライベート intは始まります。 プライベート int型エンド。 ArraySource源と、 オブジェクトのロック = 新しいオブジェクト(); SumThreadが(INT、開始INT 端を、ArraySourceソース){ この .begin = 始めます。 この .END = 終わり。 この .SOURCE = ソース; } @Override 公共 ボイドラン(){ 場合(この .SOURCE ==ヌル || この .begin> = この.ENDは){ スロー 新しい "非法入参!"(NullPointerExceptionが)。 } INT再= 0 。 INT [] = sourceArrayのこの.source.getSource()。 用(INT ; I <=エンドI ++ iは開始= {) 再 + = sourceArrayの[I]。 } 同期(ロック){ source.setResult(source.getResult() + RE)。 source.setThreadNum(source.getThreadNum() - 1)。 } } }
主な機能:
パブリック クラスは、テスト{ 公共 静的 ボイドメイン(文字列[]引数)がスローInterruptedExceptionある{ ため(INT I = 0; I <1000; I ++ ){ int型のRe = テスト(); IF(!再= 100000000 ){ のSystem.out。 printlnは( "第一" + I + + "エラーが発生し、結果は" 再); BREAK ; } } のSystem.out.println( "エンドテスト" ); } パブリック 静的 int型試験()スローInterruptedExceptionある{ INT []ソース= 新しい INT [100000000 ]。 以下のために(INT iが= 0; I <100000000; I ++ ){ 源[I] = 1 。 } 長い開始時間= にSystem.currentTimeMillis(); int型の再= 0 ; 用(INTが I = 0、I <100000000; I ++ ){ 再 + = ソース〔I〕。 } のSystem.out.println( "单线程用时为:" +(のSystem.currentTimeMillis() - BEGINTIME))。 System.out.println( "单线程结果为:" + RE)。 ArraySource arraySource = 新しい ArraySource(ソース、4 )。 SumThread thread0 = 新しい SumThread(0、20000000 、arraySource)。 SumThreadスレッド1 = 新しい SumThread(20000001、40000000 、arraySource)。 SumThreadスレッド2 = 新しい SumThread(40000001、60000000 、arraySource)。 SumThread thread3 = 新しい SumThread(60000001、99999999 、arraySource)。 // =新新SumThread SumThread(80000001、99999999、arraySource)thread4; BEGINTIME = にSystem.currentTimeMillis(); thread0.start(); thread1.start(); thread2.start(); thread3.start(); // thread4.start (); 一方(arraySource.getThreadNum()= 0!が){ // のThread.sleep(500); // するSystem.out.println( "存在" + arraySource.getThreadNum()職場+」スレッドと、電流がある: "+ arraySource.getResult()); } のSystem.out.println( "使用された場合、マルチスレッド: "+(のSystem.currentTimeMillis() - BEGINTIME)); のSystem.out.println( "マルチスレッド結果:「+arraySource.getResult())。 リターンarraySource.getResult(); } }
主な機能は、プログラムが最終的に信頼性があることが証明され、プログラムの正しさを検証するために数千回のコードを実行されます。
間違った言葉遣いを覚えておいてください:
パブリック クラスArraySource { // ソースアレイ プライベート INT []ソース; // 積算結果 プライベート int型の結果= 0 ; // 現在動作するスレッドの数 プライベート INT threadNumを、 ArraySource(INT []ソース、INT threadNum){ この .SOURCE = 光源と、 この .threadNum = threadNum; } 公共 のint []メソッドgetSource(){ 戻り 、この.SOURCEを; }
公共int型のgetResult(){
同期(本){
戻りthis.result。
}
}
公共ボイドsetResult(INT結果){
(本)同期{
this.result =もたらします。
}
}
パブリックINT getThreadNum(){
(本)同期{
this.threadNumを返します。
}
}
公共ボイドsetThreadNum(INT threadNum){
(本)同期{
this.threadNum = threadNum。
}
}
これは、書き込みに相当します。
@Override 公共 のボイドの実行(){ 場合(この .SOURCE == nullの || この .begin> = この.END){ スロー 新しい( "非法入参!" NullPointerExceptionが)。 } INT再= 0 。 INT [] = sourceArrayのこの.source.getSource()。 用(INT ; I <=エンドI ++ iは開始= {) 再 + = sourceArrayの[I]。 } INT totalRe = source.getResult()。 source.setResult(totalRe +再)。 INT sharedThreadNum = source.getThreadNum()。 source.setThreadNum(sharedThreadNum - 1 )。 }
最初のロックを取得するために、書き込み動作を解放した後、ロック読み出し動作を取得し、保証アトミック操作はありません。