0

静的同期メソッドとインスタンス同期メソッドが異なるスレッドで同じクラスの静的フィールドにアクセスしようとしている次のプログラムの動作はどうなりますか? ブロックされるスレッドはありますか? 非常に紛らわしいです。

class MyClass
{
        public static int i = 5;

        public synchronized void m1()
        {
                System.out.println(i); //uses static field i of MyClass
            //T1 is executing this method
        }

        public static synchronized void m3()
        {
            //T2 will be able to call this method on same object lock while it is using
            //static field i???
            System.out.println(i);//uses static field i of MyClass
        }
}
4

5 に答える 5

6

同期されたインスタンス メソッドは、

public void m1() {
    synchronized(this) {
        ...
    }
}

(まあ、それらはまったく同じではありませんが、あなたの質問への答えはその違いに悩まされることはありません)。

同期された静的メソッドは、クラスで同期されます。

public void m2() {
    synchronized(MyClass.class) {
        ...
    }
}

ご覧のとおり、2 つのブロックが異なるオブジェクトで同期されています。m1は呼び出されたインスタンスで同期され、JVM でクラスを表すm2インスタンスで同期されています。Class<MyClass>したがって、これら 2 つのメソッドは、互いにブロックすることなく呼び出すことができます。

于 2013-03-06T14:48:34.640 に答える
4

常にオブジェクトを同期しています。

関数 m1 は、呼び出されたオブジェクトのインスタンスで同期します。

関数 m3 は、クラス自体で同期します。

m1 は次のように記述できます。

        public void m1()
        {
            synchronized(this) { 
                System.out.println(i); //uses static field i of MyClass
                //T1 is executing this method
            }
        }

したがって、2 つの異なるオブジェクトを同期しており、これら 2 つのメソッドは任意のグローバル変数に同時にアクセスできます。

于 2013-03-06T14:43:00.937 に答える
1

サンプルコードは良さそうです。

私によると、静的変数の同期を保証する最良の方法は. ロックオブジェクトはクラス外ではアクセスできないため。下記参照。

public class MyClass
{
    private static int i = 0;
    private static final Object lockObject = new Object();

    public void m1() {
        synchronized (lockObject ) {
            //Use you static var
        }
    }

    public void m3() {
        synchronized (lockObject ) {
            //Use you static var
        }
    }
} 
于 2013-03-06T14:47:43.133 に答える
0

メソッド m1 と m3 は独立して実行できます。

あなたがすでに言っstatic synchronizedたように、オブジェクトにあるからです。したがって、 と同じsynchronize(MyClass.class)です。

synchronizedインスタンス全体で使用できます。したがって、インスタンスに対してのみブロックされます。以下を使用するのと同じです。

MyClass myClass = new MyClass();
synchronize (myClass)
{
.....
}
于 2013-03-06T14:44:18.363 に答える
-1

Java には、静的フィールドへのアクセスに関連する同期制御はありません。

メソッドを空にすると、同期はまったく同じになります。

具体的には、いずれかのスレッドがその型の同期静的メソッドを実行している限り、同期静的メソッドを呼び出す他のすべてのスレッドはそれらの終了を待機するため、一度に実行される同期静的メソッドは最大 1 つです。

于 2013-03-06T14:41:30.203 に答える