私はクラスをフォローしています
class A{
private int id =0;
public void setMessageId(Message m) {
synchronized(m) {
m.setId(id++);
}
}
}
メッセージのインスタンスが異なるクラスAの同じインスタンスを持つ2つのスレッドが同時に同期ブロックに入り、メッセージの異なるインスタンスに同じIDを設定できますか?
私はクラスをフォローしています
class A{
private int id =0;
public void setMessageId(Message m) {
synchronized(m) {
m.setId(id++);
}
}
}
メッセージのインスタンスが異なるクラスAの同じインスタンスを持つ2つのスレッドが同時に同期ブロックに入り、メッセージの異なるインスタンスに同じIDを設定できますか?
はい。id
フィールドを保持するオブジェクト (この場合は「A」) またはいくつかの共通オブジェクトを同期する必要があります。
はい。ブロックはメッセージで同期されるため、2 つの異なるメッセージ インスタンスを使用する 2 つのスレッドが同期ブロックに同時に入ることができ、両方が同じ ID を取得します。
メソッドを同期させると、すべてがうまくいきます。または、AtomicInteger を使用します。
はい、どちらも異なるオブジェクトへのロックを持っているためです。
自作の同期をまったく行わない 1 つのオプションは、AtomicIntegerを使用することです。
class A{
private final AtomicInteger id = new AtomicInteger();
public void setMessageId(Message m) {
m.setId(id.incrementAndGet());
}
}
incrementAndGetメソッドは、値を 1 ずつインクリメントし、更新された値を返します。
m のみを同期する場合、2 つのオブジェクトが A の同じインスタンスを変更できます。値 id を格納するオブジェクトを同期する必要があります。
確かに、異なるオブジェクトで同期するためです。
この目的のために必要なものがすべて ID 生成である場合は、 java.util.concurrent AtomicIntegerを使用することをお勧めします。
たとえば、次のようにします。
private AtomicInteger counter;
public int getNextUniqueIndex() {
return counter.getAndIncrement();
}
明らかに、ロックがオンになって Message m
おり、2 つのスレッドが異なるインスタンスを持っている場合Message
、それらは可能です..
1.同期ロックがメッセージのインスタンスにあるため、異なるメッセージオブジェクトを持つ2つのスレッドが同時にこのブロックに確実にアクセスできます。
2.同じインスタンス変数を設定していても、オブジェクトごとに 1 つの個人用コピーのようなものです。
3. 1 つのオブジェクトの変数 id
を変更するスレッドは、他のオブジェクトの ID には影響しません。
はい:
ロックオブジェクトは、スレッドごとに2つの異なるオブジェクトである m オブジェクトに対して取得されるため、可能です。あなたのケースでは、それらの 2 とその A クラスの間で共有されるロックを取得する必要があります。