マルチスレッドノート

理論的要約: 

  • wait、notify、notifyAllは、同期制御メソッドまたは同期制御ブロックでのみ使用できますが、sleepはどこでも使用できます。したがって、sleep()メソッドとwait()メソッドの最大の違いは、sleep()がスリープ中にオブジェクトをロックし続けることです。ただし、それでもロックを占有します。wait()がスリープしている間に、オブジェクトロックを解放します。ただし、wait()とsleep()は、interrupt()メソッドを介してスレッドの中断状態を中断できるため、スレッドはすぐにInterruptedExceptionをスローします(ただし、このメソッドはお勧めしません)。

  • notify()メソッドの実行後、現在のスレッドはオブジェクトロックをすぐに解放せず、待機状態のスレッドはオブジェクトロックをすぐに取得できません。notify()メソッドスレッドがプログラムの実行を終了するまで待機する必要があります。つまり、同期されたコードを終了します。ブロック後、現在のスレッドはロックを解放します。待機状態のスレッドのみがオブジェクトロックを取得し、wait()メソッドの後続のコードを実行できます。一文に要約すると、waitはスレッドの実行を停止し、notifyは停止したスレッドの実行を継続します。

  • notify()wait()モードを使用する場合、待機の待機条件が変化したときのプログラムロジックに特に注意してください。プログラムの異常(配列コーナーマークの範囲外の例外など)を回避するには、条件の判断にif(){...}の代わりにwhile(){...}を使用します。

  • 同じオブジェクト内の非静的同期メソッドを呼び出すスレッドは、互いにブロックします。それが異なるオブジェクトである場合、各スレッドには独自のオブジェクトロックがあり、スレッドは互いに干渉しません。

  • 同じクラスの静的同期メソッドを呼び出すスレッドは互いにブロックし、それらはすべて同じクラスオブジェクトにロックされます。

  • 静的メソッドはClassオブジェクトでロックされ、非静的メソッドはクラスのオブジェクトでロックされるため、静的同期メソッドと非静的同期メソッドが互いにブロックすることはありません。

  • Interrupted()は静的メソッドです。内部実装は呼び出された現在のスレッドのisInterrupted()であり、現在のスレッドの中断状態をリセットします。isInterrupted()はインスタンスメソッドであり、これはのisInterrupted()です。メソッドを呼び出したオブジェクトによって表されるスレッド)、現在のスレッドの割り込みステータスはリセットされません。

  • yield()の機能は、譲歩することです。これにより、現在のスレッドが「実行状態」から「準備完了状態」に入ることができ、同じ優先順位を持つ他の待機中のスレッドが実行権を取得できるようになります。ただし、現在のスレッドがyield()を呼び出した後、他のスレッドの優先度は同じです。スレッドは実行権を取得できる必要があります。現在のスレッドが「実行状態」に入って実行を継続できる可能性もあります。
  • wait()の機能は、現在のスレッドを「実行状態」から「待機(ブロック)状態」にすると同時に、同期ロックを解除することです。yield()の関数は譲歩することであり、現在のスレッドを「実行状態」から解放します。違いは次のとおりです。
    (01)wait()は、スレッドを「実行状態」から「待機(ブロック)状態」にしますが、yield()は、スレッドを「実行状態」から「準備完了状態」にします。 。
    (02)wait()はスレッドによって保持されているオブジェクトの同期ロックを解放しますが、yield()メソッドはロックを解放しません。
  • デーモンスレッドはユーザースレッドに依存しています。ユーザースレッドが終了すると、デーモンスレッドも終了します。一般的なデーモンスレッドはガベージコレクションスレッドです。デフォルトで開始されるスレッドはユーザースレッドです。スレッドはsetDaemon(true)によってデーモンスレッドとして設定されます。この関数は、スレッドが開始される前に呼び出す必要があります(start()メソッド)。そうでない場合、java.lang.IllegalThreadStateExceptionが報告されます。スレッドはデーモンスレッドになることはできませんが、ユーザースレッドになることができます。デーモンスレッドは、ファイルやデータベースなどの固有のリソースにアクセスしないでください。これは、デーモンスレッドがいつでも、または操作の途中でさえも中断されるためです。

  • InheritableThreadLocalクラスを使用して、子スレッドが親スレッドから値を取得できるようにします。値はデフォルト値を継承します。InheritableThreadLocalを継承するクラスがinitiaValue()メソッドをオーバーライドするようにします。値の継承と変更:InheritableThreadLocalを継承するクラスがchildValue()メソッドをオーバーライドするようにします。

  • ReentrantReadWriteLock読み取り/書き込みロック。読み取りと読み取りの共有、書き込みと読み取りの相互排除、読み取りと書き込みの相互排除、書き込みと書き込みの相互排除、  読み取りロック:lock.readLock()。lock();書き込みロック:lock.writeLock()。lock();

  • ダブルチェックロック機能(DCL)を使用して、「レイジーマンモード」で発生したマルチスレッドの問題を正常に解決しました。同期コードを必要とせずに非同期実行を保証するだけでなく、シングルトンの効果も保証します。

 

sleep()メソッド:

  • sleep()は、現在のスレッドを停滞状態にし(現在のスレッドをブロックし)、CUPの使用を断念します。目的は、現在のスレッドがプロセスのみで取得したCPUリソースを占有しないようにして、そのままにすることです。他のスレッドが実行される特定の時間。

  •  sleep()はThreadクラスの静的(静的)メソッドであるため、オブジェクトのマシンロックを変更することはできません。したがって、Sleep()メソッドがSynchronizedブロックで呼び出されると、スレッドはスリープしますが、オブジェクトは存在しません。解放された後、他のスレッドはオブジェクトにアクセスできません(オブジェクトがスリープ状態であっても、オブジェクトのロックを保持します)。

  • sleep()スリープ時間が経過した後、他のスレッドが実行されていて、このスレッドの優先度が高い場合を除いて実行を中止するようにスケジュールされていないため、スレッドがすぐに実行されない場合があります。 

 

wait()メソッド:

  • wait()メソッドはObjectクラスのメソッドです。スレッドがwait()メソッドを実行すると、オブジェクトに関連付けられた待機プールに入り、同時にオブジェクトのマシンロックを失います(解放します)。一時的にマシンを失います)ロック、待機(長いタイムアウト)タイムアウトの期限が切れた後にオブジェクトロックを返す必要があります);他のスレッドがアクセスできます;
  • wait()は、notifyまたはnotifyAlllを使用するか、現在の待機プール内のスレッドをウェイクアップするためのスリープ時間を指定します。
  • wiat()は同期ブロックに配置する必要があります。そうしないと、プログラムの実行時に「java.lang.IllegalMonitorStateException」例外がスローされます。

 

join()メソッド:

 

sleep()とyield()の違い:

  • sleep()とyield()の違い:sleep()は現在のスレッドを停滞状態にするため、sleep()を実行するスレッドは指定された時間内に実行されません。yield()は現在のスレッドを作成するだけです。実行状態に戻るため、yield()を実行するスレッドは、実行可能状態に入った直後に実行される可能性があります。
  • sleepメソッドは、現在実行中のスレッドを一定期間スリープさせ、操作不能状態にします。この期間の長さはプログラムによって設定されます。yieldメソッドは、現在のスレッドにCPU所有権を放棄させますが、放棄時間はできません。設定する。実際、yield()メソッドは、次の操作に対応します。最初に、同じ実行可能状態で同じ優先度のスレッドが現在存在するかどうかを確認します。存在する場合は、CPU所有権をこのスレッドに転送します。存在しない場合は、元のスレッドの実行を続行します。 。したがって、yield()メソッドは「yielding」と呼ばれ、同じ優先度の他のスレッドに実行する機会を放棄します。
  • さらに、sleepメソッドを使用すると、優先度の低いスレッドを実行する機会を得ることができますが、yield()メソッドを実行しても、現在のスレッドは実行可能な状態のままであるため、優先度の低いスレッドに実行させることはできません。しばらくの間CPUの所有権。実行中のシステムでは、優先度の高いスレッドがsleepメソッドを呼び出さず、I \ Oによってブロックされていない場合、優先度の低いスレッドは、優先度の高いすべてのスレッドが終了するのを待ってから、実行します。 

 

 

一般的なスレッド用語の説明:

メインスレッド: JVM呼び出しプログラムmain()によって生成されたスレッド。
現在のスレッド:これは紛らわしい概念です。通常、Thread.currentThread()を介して取得されるプロセスを指します。
バックグラウンドスレッド:デーモンスレッドとも呼ばれる、他のスレッドにサービスを提供するスレッドを指します。JVMのガベージコレクションスレッドはバックグラウンドスレッドです。ユーザースレッドとデーモンスレッドの違いは、メインスレッドが終了するのを待つかどうかは、メインスレッドが
フォアグラウンドスレッドを終了するかどうかに依存することです。実際には、フォアグラウンドとバックグラウンドでバックグラウンドスレッドサービスを受け入れるスレッドを指します。スレッドは、人形と舞台裏のマニピュレータの関係のように、互いにリンクされています。パペットは前景のスレッドであり、マニピュレータは背景のスレッドです。フォアグラウンドスレッドによって作成されたスレッドは、デフォルトではフォアグラウンドスレッドでもあります。isDaemon()メソッドとsetDaemon()メソッドを使用して、スレッドがバックグラウンドスレッドであるかどうかを判別および設定できます。
スレッドクラスのいくつかの一般的なメソッド: 

  sleep():スレッドを強制的にNミリ秒スリープさせます。 
  isAlive():スレッドが生きているかどうかを判別します。 
  join():スレッドが終了するのを待ちます。 
  activeCount():プログラム内のアクティブなスレッドの数。 
  enumerate():プログラム内のスレッドを列挙します。 
       currentThread():現在のスレッドを取得します。 
  isDaemon():スレッドがデーモンスレッドであるかどうか。 
  setDaemon():スレッドをデーモンスレッドとして設定します。(ユーザースレッドとデーモンスレッドの違いは、メインスレッドの終了に応じてメインスレッドが終了するのを待つかどうかです) 
  setName():スレッドの名前を設定します。 
  wait():スレッドを強制的に待機させます。 
  notify():実行を継続するようにスレッドに通知します。 
  setPriority():スレッドの優先度を設定します。

ブログリファレンス: 

Javaマルチスレッド学習(吐血超詳細要約)

Synchronized(オブジェクトロック)とStatic Synchronized(クラスロック)の違い 

同期方法と同期コードブロックの違い 

スレッドのinterrupted()メソッドとisInterrupted()メソッドの違いの要約

Javaマルチスレッドシリーズカタログ(合計43の記事)

おすすめ

転載: blog.csdn.net/xiangwang2016/article/details/92794468