高度なマルチスレッドのJava構文10-

マルチスレッド

並行性と並列プロセス、スケジュールスレッド独自のBaiduのを

スレッド(スレッド):実行パスをスケジューリングするのに基本ユニットのCPUスケジューリングプロセスです。同じプロセスのスレッドがいくつかのメモリ(ヒープ、メソッド領域)を共有することができ、各スレッドは、独自の独立した空間(スタック、プログラムカウンタ)を有します。そのため、データの共有という点でスレッド間での共有メモリ、の、より便利にするだけでなく、ためにデータの共有のため、スレッド安全性の問題があるでしょう。

Javaプログラムを実行している場合、実際には、すでにそれは、スレッドがあり、それがメインスレッドです。

Threadクラス

すべてのスレッドオブジェクトは、Threadクラスまたはサブクラスのインスタンスでなければなりませんに継承を通じてのJava Threadクラスを作成し、マルチスレッドの起動手順は以下のとおりです。

  1. Threadクラス、クラスおよびオーバーライドrun()メソッドのサブクラスの定義は、run()メソッドのメソッド本体は、run()メソッドが実行スレッドと呼ばれているので、タスクを完了するために、スレッドのニーズを表しています。

  2. スレッドのサブクラスのインスタンスを作成し、スレッドオブジェクトが作成されます

  3. スレッドを開始するスレッドオブジェクトのstart()メソッドを呼び出します

、Runnableインタフェース

また、Runnableを、オーバーライドrun()メソッドを実装して、オブジェクトを介してエージェントとThreadクラスの当社実行ボディのスレッド()メソッドの実装を開始することができます。次のステップ:

  1. 実行可能なインターフェイス実装クラスが定義され、実行スレッドの同じスレッドのインタフェースとオーバーライドrun()メソッド、メソッド本体のrun()メソッド。

  2. Runnableを実装クラスのインスタンスを作成し、ターゲットとしてスレッドThreadオブジェクトのインスタンスを作成するためにそれを使用し、Threadオブジェクトは本物だスレッドオブジェクト。

  3. スレッドを開始するスレッドオブジェクトのstart()メソッドを呼び出します。

例:実装クラスのスレッドを定義//パブリッククラスMyRunnable実装Runnableを

    MyRunnable MRは=新しいMyRunnable(); //スレッドオブジェクトを作成

         スレッドTは、新しいスレッド(MR)= ; // 例としてThreadクラスを、スレッド開始
          t.start();

スレッド実行の事実上すべてのマルチスレッドコードは、開始によるものである()メソッドを実行します。したがって、スレッドのクラスを継承または実装するかどうかを最終的にスレッドクラスAPIに精通APIスレッドスレッドオブジェクトによって制御され、マルチスレッド達成するために、Runnableインタフェースをマルチスレッドプログラミングの基礎です。

ヒント:Runnableをのみ、対象Threadオブジェクトなどのオブジェクト、Runnableをクラス備えるが、実行の唯一のスレッドとしてrun()メソッドを実装します。実際のスレッドオブジェクトは、ちょうどこのスレッドのスレッドがそのターゲットの実行()のメソッドの実装を担当して、まだスレッドインスタンスです。

二つのアプローチの違い

図1に示すように、単一継承制限継承、達成することができるよりも多くを達成する方法

2、異なる起動モード

3.継承:共有データを実装する際に静的である必要があるかもしれません

  実装:長いRunnableを実装クラスのシェアと同じオブジェクトをすることができます。

4.継承:あなたはこのロックを選択し使用することはできません、

  実装:あなたはこのロックを使用することができます選択します。

匿名内部クラスのオブジェクトが作成したスレッドを実装するために開始します

( "!新しいスレッド"){スレッド新しい新しい
  @Override
  ます。public void RUN(){
    のために(int型I = 0; I <10; I ++){
      System.out.printlnは(のgetName()+ ":!実行されています" + I);
    }
  }
} .start();

コンストラクタ

公共のスレッド():割り当て新しいThreadオブジェクト。

公共のスレッド(文字列名):新しいスレッドオブジェクトに指定された名前を割り当てます。

公共のスレッド(Runnableを対象):割り当て指定されたターゲットを持つ新しいThreadオブジェクト。

公共のスレッド(Runnableをターゲット、文字列名):指定された目標に、新しいスレッドオブジェクトを割り当て、名前を指定します。

一般的な方法をスレッド

揮発性:修正変数

どの時点で必ずしも変数の値は、メインメモリからの値にするたびに、それはレジスタの値をキャッシュされませんので、揮発性を修正した後、常に最新の値を取得するために、変更されますされていません。

デーモンスレッド

デーモンスレッドは、すべての非デーモンスレッドが死亡している場合、デーモンスレッドが自動的に殺されるという特徴を有しています。

コールは、setdaemon(true)メソッドは、デーモンスレッドとして指定されたスレッドを設定することができます。スレッドが開始される前に、それはそれ以外の場合はないIllegalThreadStateException例外が報告されます、設定する必要があります。

スレッドはデーモンスレッドであるかどうかを判断できisDaemon()を呼び出します。

スレッドセーフ

裁判官スレッドの安全性の問題

1、複数のスレッドがある場合

共有データに、複数のスレッドを使用するかどうか2、

図3に示すように、これらのスレッドリードライトがあるかどうか、共有データを使用して

シンクブロック

同期キーワードは、ブロックのプロセスで使用することができ、それだけ、このブロックのリソースへの相互排他的なアクセスを強制することを示しています。フォーマット:

同期(シンクロック){
     必要コード同期動作
}

同期ロックがオブジェクトである必要があります

ロックオブジェクトは、どのようなタイプのものとすることができます。

複数のスレッドオブジェクトが使用する必要があります同じロックを注:いずれかの時点で、最大で1つのスレッドがブロック上のロックに入った同期ロックを所有することができ、他のスレッドは外側だけ待つことができる(ブロック)。

同期方法

使用同期修正方法を、と呼ばれる同期メソッドは、メソッドを実行するときにロックを保持しているスレッドは、他のスレッドが唯一の方法であることができることを確実にするために待っています

] [同期他の修飾戻り型メソッド名(パラメータリストは、[])例外リストをスロー] [{
     //コードは、スレッドの安全性の問題を生じさせることができます
}

ロックオブジェクトは、私たち自身で選択することができない、それがデフォルトです。

(1)静的メソッド:ロックオブジェクトは、現在のクラスのクラスのオブジェクトであります

(2)非静的な方法:本

スレッド間通信

ときに起こされるのを待って、待ちにフル、「プロデューサー」の必要性を「データがバッファ」。

「データバッファ」ときに起こされるのを待って、待ちに「消費者」の必要性を空にする。

ときに、スレッドが出会う特定の条件、待機状態(入力するように待機() / 待機(時間))、およびそれが(彼らの他のスレッドを実行するために指定されたコードの完了後に目を覚ますのを待つ通知());またはあなたがの待機時間を指定することができます、時間ので、自動的にウェイクアップするために、待つため、複数のスレッドがある場合には、必要に応じて、使用のnotifyAll()は、すべての待機中のスレッドをウェイクアップします。

  1. 待機:スレッドがそうWAITINGまたはTIMED_WAITINGある状態をスレッド、その後、ない競合ロックに、CPUリソースを無駄にしない、待機セットに、スケジューリングに関与しなくなった、もはや有効です。それはを待つ必要が実行する他のスレッド特定のアクションを「である、(通知)の通知」または(レディキューを待機セットから解放されたスレッドを待って、このオブジェクトには、までの時間を待ち、ディスパッチキューに再入力してください)で

  2. 通知:通知対象スレッドの待機セットがリリースに選択されています。

  3. notifyAll:通知オブジェクト待ちセット上のすべてのスレッドが解放されます。

注意:

それは場所を中断していたので、通知し、直ちに実行スレッドを再開することができない可能性が目覚めた後のシンクブロックではありませんが、彼女は(おそらく他のスレッドに直面してロックを獲得するために、再試行してくださいする必要がありますので、現時点ではそれはもはや、ロックを保持しています競争が)、成功した後、元のコール待ちメソッドの後の場所で実行を再開することができます。

次のように要約:

  • あなたがロックを取得できた場合は、スレッドがWAITING状態からRUNNABLE(実行)状態になります。

  • そうでない場合は、待ち状態からのスレッドがブロックされてしまう(ロック待ち)状態

待機を呼び出し、通知方法は細部に注意を払うに必要

  1. 待って、通知方法の方法は、同じロックオブジェクトによって呼び出される必要があります。ので:対応するロックオブジェクトは、ロックオブジェクトでwaitメソッドの呼び出し後、スレッドの使用を通知復帰させることができます。

  2. 通知し、waitメソッドは、オブジェクトのクラスに属するメソッドです。ので:ロックオブジェクトは、任意のオブジェクトにすることができ、クラスに属する任意のオブジェクトは、Objectクラスを継承しています。

  3. 通知及び待機メソッドは、同期コード・ブロックまたは同期機能の方法で使用されなければなりません。そのため:2つのロックオブジェクトを介してこのメ​​ソッドを呼び出す必要があります。

古典的な「生産者 - 消費者」問題を解決するためにウェイクアップ機構を待って

この問題を解決するために、我々は、バッファ内のプロデューサーのスレッドが待機をさせなければならない、ブロックされた状態に一時停止(待機)、フルである、通知(通知)スレッドが再開を待っているときに、バッファ内の次の消費者の消費データまで待ちます準備完了状態に、バッファへのデータの追加を開始。そして、その逆

ライフサイクルスレッド

まず、放置するスレッドの角度:5種類

1、新:スレッドオブジェクトを作成し、まだ開始

2、準備ができて:すでに開始し、CPUスケジューリングすることができ

3、実行:スケジュール設定されています

図4は、ブロック:会った:睡眠()、待機()、待機(時間)、他のスレッドは、(参加)、(時間)に参加、)(一時停止、ロックはなど、他のスレッドによって占有されています

  戻るブロック解除準備状態に:時間、履歴書()にストッパー、ねじ止めの終わりにスリープ()時間、通知()、待ち時間、ロックを保持している他のスレッドがロックを解放。

5、死:通常、未処理の例外やエラー、停止(遭遇し、実行()は終了)

注意:

新しい状態プログラムのみ)の呼び出しは(開始スレッドができ、新たな非国家のスレッドとして開始されたスレッドやスレッドがスタートを呼び出して死亡した場合にのみ、一回呼び出すことができます()ないIllegalThreadStateException例外をエラーになります。

第二に、コードの6種類のスタンド角度

クラスで定義されているような列挙java.lang.Thread.State

パブリック列挙州{
  NEW、
  RUNNABLE、
  BLOCKED、
  WAITING、
  TIMED_WAITING、
  TERMINATED。
}

1、新NEW:スレッドオブジェクトを作成し、まだ開始

2、RUNNABLEを実行します:CPUは、スケジュールすることができ、または予定されています

3、ブロックされたBLOCKED:ロックを待機

図4に示すように、ウェイトWAITING:待機())、(参加)等(通知しなければならない等、全く設定された時間がない、または再開する糸の端栓

スリープ(時間)、待機(時間)、(時間)に参加し、その時間ブロッキングを持って、時間が回復するので、または割り込みが復元されます:5は、TIMED_WAITINGを待つ時間があります

図6に示すように、終了は終了:正常に処理されない例外またはエラーが発生しましたラン()の端部を、停止()

操作とロックデッドロックを解除します

同期ブロックに任意のスレッドは、同期方法の前に、あなたは、第1のモニタの同期のロックを取得しなければならないので、同期監視、それにロックを解放するとき?

1、ロックの解除操作

現在のスレッド同期方法、同期コードブロックの実行が終了します

現在のスレッドが現在のスレッドの異常終了の結果、未処理のエラーまたは例外ブロック同期コード、同期プロセスが登場しました。

現在のスレッドがコードブロックの同期ロックオブジェクト、同期方法の実行待ち()メソッドは、現在のスレッドは中断され、ロックを解除されています。

2、ロック操作を解放しません

线程执行同步代码块或同步方法时,程序调用Thread.sleep()、Thread.yield()方法暂停当前线程的执行。

线程执行同步代码块时,其他线程调用了该线程的suspend()方法将该线程挂起,该线程不会释放锁(同步监视器)。应尽量避免使用suspend()和resume()这样的过时来控制线程。

3、死锁

不同的线程分别锁住对方需要的同步监视器对象不释放,都在等待对方先放弃时就形成了线程的死锁。一旦出现死锁,整个程序既不会发生异常,也不会给出任何提示,只是所有线程处于阻塞状态,无法继续。

 

おすすめ

転載: www.cnblogs.com/Open-ing/p/11953108.html