8

コンストラクターは作成できませんが、コンストラクター内にsynchronized記述できますsynchronized。どのような場合にそのような要求が来るのでしょうか? 私は面白がっています。

package com.simple;
public class Test {
    public Test() {
        synchronized (this) {
            System.out.println("I am called ...");
        }
    }

    public static void main(String[] args) {
        Test test=new Test();   
        System.out.println(""+test);
    }

    @Override
    public String toString() {
        return "Test []";
    }
}
4

7 に答える 7

10

コンストラクター内で新しいスレッドを開始できます。それは非常に珍しいことです - そして確かにあなたが提供したコードでは無意味でしょう - しかし、それは起こる可能性があります.

言語は通常、無意味な可能性のあるすべてのことを見つけようとはしません。これは、非常に複雑な言語仕様につながります。言語の使用者側にも、ある程度の考慮が必要です...

于 2013-02-22T10:17:07.830 に答える
6

同期は、コンストラクターからthis漏れていることを意味するため、悪い習慣の兆候ですthis。これは、同じオブジェクトで他のコードを同期させる唯一の方法です。

ただし、他の一般的なロックで同期することは正当である可能性があります。コンストラクターは、実際にそのような同期を必要とするコードを呼び出す必要があります。

于 2013-02-22T10:18:26.107 に答える
0

私が理解している限り、コンストラクター内の静的フィールドを扱う場合、それは重要になる可能性があります。オブジェクトが作成中の場合、オブジェクトを作成しているスレッドのみがこのオブジェクトにアクセスできますが、コンストラクターの静的フィールド値が変更された場合、2 つの異なるスレッドが同じクラスのオブジェクトを同時に作成できるため、関連する競合が発生する可能性があるため、問題になる可能性があります。静的フィールドに。しかし、これをロックに使用するのが良い考えかどうかはわかりません

于 2015-09-18T20:18:31.820 に答える
0

複数のスレッドによってアクセスされるコンストラクターの共通データを変更している可能性があります。より良いシンプルなアプローチが好まれますが。

于 2013-02-22T10:21:08.193 に答える
0

通常の状態では、そうする理由はないはずです。

ただし、参照をコンストラクターから「エスケープ」させる場合this(もちろん、これは悪い習慣です)、他の操作を呼び出す前に、同期ブロックが完了するまでクライアント コードを強制的に待機させたい場合があります。

例えば:

class C {
    public C() {
        // ....
        synchronized(this) {
            someService.doSomethingWith(this);
            // some other critical stuff...
        }
    }

    public synchronized void criticalSection() {
        // ...
    }

}

この例では、criticalSection()内部someServiceで呼び出すと、コンストラクター内の同期ブロックが完了するまで待機する必要があります。

ただし、これはお勧めできませんthis。コンストラクターをエスケープすることは絶対に許可しないでください。

于 2013-02-22T10:23:27.783 に答える