私は 1Z0-851 Oracla Java SE 1.6 認定のために勉強していて、次の質問を見ました。
誰かが私にこの答えを説明できますか?
そして、私がこのように考えるとき、私が正しいかどうかを言います:doThings()
メソッドがstatic
1回ではない場合でも、静的である場合、各TestSeven
オブジェクトが同時にdoThingsにアクセスし、x値を一貫性なく変更するにもかかわらず、1回だけアクセスできます。
このように考えるのは正しいですか?
ありがとう。
私は 1Z0-851 Oracla Java SE 1.6 認定のために勉強していて、次の質問を見ました。
誰かが私にこの答えを説明できますか?
そして、私がこのように考えるとき、私が正しいかどうかを言います:doThings()
メソッドがstatic
1回ではない場合でも、静的である場合、各TestSeven
オブジェクトが同時にdoThingsにアクセスし、x値を一貫性なく変更するにもかかわらず、1回だけアクセスできます。
このように考えるのは正しいですか?
ありがとう。
はい、それだけです。現時点では、 の 2 つのインスタンスを作成し、2 つの異なるスレッドからTestSeven
そのメソッドを呼び出した場合、2回インクリメントされる保証はありません。たとえば、次の実行は有効です (T1 と T2 は 2 つのスレッドです)。doThings
x
T1: current = x //0
T2: current = x //0
T1: current++; // 1
T2: current++; // 1
T1: x = current; // 1
T2: x = current; // 1
したがって、メソッドを 2 回呼び出しましたが、x は 1 回だけインクリメントされています。
メソッドを静的にすると、多くのインスタンスを作成しても、特定の時点で 1 つのスレッドしか実行できなくなります。
xスコープは「静的」であるため、スレッドセーフではありません。つまり、すべてのクラスインスタンスがアクセスできますが、 doThingsメソッドはそうではありません。そのため、クラス インスタンスでのみ同期されます。
したがって、 synchronized キーワードにもかかわらず、同時にxにアクセスする 2 つのクラス インスタンスが存在する可能性があります。
メソッドを静的にすると、一度に 1 回だけ呼び出されるようになります。
メソッドはインスタンス メソッドであり、静的変数のdoThings()
読み取りと書き込みを行っていますx
。静的にすることdoThings()
で、すべてのインスタンス間で同期されます (インスタンスではなく、クラスに対する固有のロック)。つまり、現状ではメソッドを複数のスレッドから同時に呼び出すことができますが、静的にするとそれが妨げられます。
x が static とマークされていない場合、クラスはスレッドセーフになりますか?