質問

Javaの同期方法と同期ブロックの違いは何ですか?

私はネット上で答えを検索しています、人々はこれについてとても確信がないようです:-(

私の見解は、2つの間に違いはありませんが、同期ブロックの範囲がよりローカライズされている可能性があるため、ロックは時間が短くなることを除いて??

そして、静的方法のロックの場合、ロックは何ですか?クラスのロックの意味は何ですか?

役に立ちましたか?

解決

同期されたメソッドは、メソッドレシーバーをロックとして使用します(つまり this 非静的な方法の場合、および静的メソッド用の囲いクラスの場合)。 Synchronized ブロックは、式をロックとして使用します。

したがって、次の2つの方法は、将来のロックと同等です。

synchronized void mymethod() { ... }

void mymethod() {
  synchronized (this) { ... }
}

静的方法の場合、クラスはロックされます。

class MyClass {
  synchronized static mystatic() { ... }

  static mystaticeq() {
    syncrhonized (MyClass.class) { ... }
  }
}

同期したブロックの場合、任意の非任意のブロックを使用できますnull ロックとしてのオブジェクト:

synchronized (mymap) {
  mymap.put(..., ...);
}

ロックスコープ

同期されたメソッドの場合、ロックはメソッドスコープ全体に保持されますが、 synchronized ブロック、ロックはそのブロックスコープ(別名クリティカルセクションとも呼ばれます)の間にのみ保持されます。実際には、JVMは、一部の操作を削除することにより、最適化することが許可されています。 synchronized 安全に実行できることを証明できる場合、実行をブロックします。

他のヒント

同期された方法は速記です。これ:

class Something {
    public synchronized void doSomething() {
        ...
    }

    public static synchronized void doSomethingStatic() {
        ...
    }
}

すべての意図と目的について、これに相当します。

class Something {
    public void doSomething() {
        synchronized(this) {
            ...
        }
    }

    public static void doSomethingStatic() {
        synchronized(Something.class) {
            ...
        }
    }
}

(どこ Something.class クラスのクラスオブジェクトです Something.)

したがって、同期したブロックを使用すると、ロックについてより具体的にすることができ、いつ使用したいかについてはより細かくなりますが、それ以外は違いはありません。

はい、それは一つの違いです。もう1つは、他のオブジェクトのロックを取得できることです。 this.

重要な違いは次のとおりです。同期する方法を宣言すると、メソッドの全身が同期されます。ただし、同期ブロックを使用する場合は、同期ブロックのメソッドの「重要なセクション」のみを囲むことができ、メソッドの残りの部分をブロックから外します。

メソッド全体が重要なセクションの一部である場合、事実上違いはありません。そうでない場合は、重要なセクションの周りに同期ブロックを使用する必要があります。同期したブロックにあるステートメントが多いほど、全体的な並列性が少なくなるため、それらを最小限に抑えます。

同期されたメソッドは、オブジェクトインスタンスにロックされています。メソッドは含まれています。

同期されたブロックとして任意のオブジェクトをロックできる場合 - 通常、インスタンス変数として定義されるミューテックスObect。これにより、どのロックが動作しているかをさらに制御できます。

私の見解は、2つの間に違いはありませんが、同期ブロックの範囲がよりローカライズされている可能性があるため、ロックは時間が短くなることを除いて??

はい。あなたが正しいです。ようではない synchronized 方法、同期されたステートメントは、本質的なロックを提供するオブジェクトを指定する必要があります。

Javaチュートリアルの例:

public void addName(String name) {
    synchronized(this) {
        lastName = name;
        nameCount++;
    }
    nameList.add(name);
}

同期されたステートメントは、細粒の同期を伴う並行性を改善するのにも役立ちます。以下のユースケースの同じチュートリアルページで良い例を見つけることができます。

たとえば、クラスを想定してください MsLunch 一緒に使用されることのない2つのインスタンスフィールド、C1とC2があります。これらのフィールドのすべての更新は必要です synchronized, 、しかし、C1の更新がC2の更新でインターリーブされるのを防ぐ理由はありません。そうすることで、不必要なブロッキングを作成することで同時性が低下します。 同期されたメソッドを使用するか、これに関連付けられたロックを使用する代わりに、ロックを提供するためだけに2つのオブジェクトを作成します.

そして、静的方法のロックの場合、ロックは何ですか?クラスのロックの意味は何ですか?

この場合、スレッドはクラスに関連付けられたクラスオブジェクトの固有のロックを取得します。したがって、クラスの静的フィールドへのアクセスは、クラスの任意のインスタンスのロックとは異なるロックによって制御されます。

あなたが方法を作るとき 同期 (非 static ) :

の2つの呼び出しでは不可能です synchronized インターリーブする同じオブジェクト上のメソッド。 1つのスレッドがオブジェクトの同期メソッドを実行しているとき、最初のスレッドがオブジェクトで実行されるまで、同じオブジェクトブロックの同期されたメソッドを呼び出す他のすべてのスレッド(実行実行)を実行します。

次のようにメソッドを作成する場合 static synchronized :

の2つの呼び出しでは不可能です static synchronized 同じクラスの異なるオブジェクトの方法からインターリーブします。 1つのスレッドが実行されているとき static synchronized クラスAのオブジェクトの方法、呼び出す他のすべてのスレッド static synchronized メソッド実行で最初のスレッドが実行されるまで、クラスAブロックのオブジェクト(停止実行)のいずれかのメソッド。

この質問では、同期のより良い代替手段があります。

Javaで同期(これ)を避けますか?

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top