web-dev-qa-db-ja.com

マルチスレッドJavaで静的メソッドを使用することについて混乱していますか?

静的についての何か:

  • クラスのインスタンスは静的メソッドを共有します

同様の質問:

私は混乱しています:

  • 静的メソッドにはメモリブロックが1つしかありませんか?
  • マルチスレッドで静的メソッドを使用すると、ブロックされますか?
11
freeeze king

私は混乱しています:

静的メソッドにはメモリブロックが1つしかありませんか?マルチスレッドで静的メソッドを使用すると、ブロックされますか?

Javaのstaticキーワードは、単に「オブジェクトの特定のインスタンスを考慮または認識せずに」を意味します。

インスタンスメソッドはthisを使用して関連するインスタンスのフィールドにアクセスできますが、静的メソッドには関連するインスタンスがないため、thisは意味がありません。

マルチスレッドでは、スレッドの安全性には、可変データの一貫性と整合性の保護が含まれます。オブジェクトはインスタンスフィールドの状態をカプセル化するため、インスタンスメソッドは、複数のスレッドが同じオブジェクトにアクセスする状況でスレッドの安全性のみを考慮する必要があります。

そのため、オブジェクトのスレッド制限はクラスのインスタンスに対して有効なスレッドセーフポリシーですが、静的メソッドにはインスタンスがないため、この同じ理由付けは無効です。

これは、メモリブロックとはまったく関係ありません。単にアクセスに関係しています。オブジェクトインスタンスには、参照を介してアクセスします。参照がスレッド制限されている場合、その参照が指すオブジェクトは常にスレッドセーフになります。ただし、クラスにアクセスできる任意の場所のスレッドは、静的メンバーを使用するためにインスタンスへの参照が必要ないため、潜在的に静的メンバーに到達できます。

静的メソッドはデフォルトでは非ブロッキングです。独自の同期/スレッドセーフポリシーを実装し、必要に応じて静的メソッドをブロックすることができます。

11
scottb

静的メソッドにはメモリブロックが1つしかありませんか?

いいえ、メソッドにはメモリブロックがありません。これらのメソッドを実行するスレッドは実行します。各スレッドは、すべてのメソッド引数と変数を格納するスタック上に独自のメモリを持ちます。

マルチスレッドで静的メソッドを使用すると、ブロックされます

スレッドは別のスレッドのメモリにアクセスすることはできませんが、すべてのインスタンスに属し、順次アクセスされることになっているリソースがある場合、 同期またはロック 静的メソッドを使用して、ブロックします。そうでなければ、いいえ。

8
YoungSpice

スレッドがローカルフレームを保持するスタックフレームを割り当てるメソッド(静的または仮想)を呼び出すたびに、各スレッドには独自のスタックスペースがあります。これについては、静的メソッドに固有のものはありません。

静的メソッドは、呼び出し側がロックを取得することを要求するなど(特にsynchronizedキーワードを使用するなど)、特にそれを阻止するための何かをしない限り、複数のスレッドによって同時に呼び出すことができます。

静的メソッドは、共有状態がない場合に適しています。それらは、どのレベルの並行性が必要か、そしてアクセスされるスレッドセーフなものがどれだけ効率的であるかに応じて、スレッドセーフな共有状態にアクセスしたり変更したりする場合には問題ないかもしれません。

ボトルネックに注意してください。静的メソッドにsynchronizedキーワードを設定すると、アプリケーションが一度に1つのスレッドのみを使用して呼び出すことに制限されるため、問題になる場合があります。アトミックオブジェクトの使用、高度な同時実行性のために設計されたスレッドセーフデータ構造の使用、またはスレッドの閉じ込めの使用を含む代替戦略は、ロックよりも好ましい場合があります。

5
Nathan Hughes