1

私は、元々 (私が信じている) IBM developerworks サイトからのスレッド化チュートリアルを読んでいました。その中で、彼らは synchronized キーワードと、コードのブロック自体ではなく、実際のオブジェクトによって同期されたコードのブロックがどのようにロックされるかについて話しました。

たとえば、以下のコードでは、作成者は、静的クラス '<code>Thingie のsetLastAccessメソッドが同期化されているとリストされていても、その下で定義されている 2 つのスレッドはsetLastAccess、thingie に異なる値を使用しているため、それぞれ同時に呼び出すことができると述べています。しかし、thingie が静的である場合、それは同じ値を使用していることを意味しませんか?

同じオブジェクトを参照している場合でも、変数名が異なるだけでよい場合はありますか?

public class SyncExample {
    public static class Thingie {
        private Date lastAccess;
        public synchronized void setLastAccess(Date date) {
            this.lastAccess = date;
        }
    }
    public static class MyThread extends Thread {
        private Thingie thingie;
        public MyThread(Thingie thingie) {
            this.thingie = thingie;
        }
        public void run() {
            thingie.setLastAccess(new Date());
        }
    }
    public static void main() {
        Thingie thingie1 = new Thingie(),
        thingie2 = new Thingie();
        new MyThread(thingie1).start();
        new MyThread(thingie2).start();
    }
} 
4

4 に答える 4

6

staticメソッドと static classを混同しています。setLastAccessが静的メソッドである場合、それが としてマークされている場合、インスタンスでsynchronizedロックされます-- ローダーごとにこれらのうちの 1 つだけがあります。メソッドが静的で同期されている場合、スレッドは同じオブジェクトをロックします。ClassClassLoader

ただし、あなたの例では、Thingie クラスはメソッドではなく静的としてマークされています。クラスの static キーワードはThingie、外部SyncExampleクラスに関連付けられていないことを意味します。これは、のインスタンスが 1 つしかThingieなく、同期に影響を与えないことを意味しません。したがって、あなたの例では、setLastAccessがマークされている場合、クラスのインスタンス( )synchronizedをロックしています。2 つのインスタンス (と) があるため、ロックは異なるオブジェクトにかかっています。明らかに、両方のスレッドが渡された場合、両方とも同じオブジェクトでロックされます。Thingiethisthingie1thingie2thingie1

ここにいくつかの読みがあります:

于 2011-10-18T18:11:02.327 に答える
4

このコード:

class SomeClass {
    public synchronized void setLastAccess(Date date) {
    }
}

以下と同じです:

class SomeClass {
    public void setLastAccess(Date date) {
        synchronized(this) {
        }
    }
}

そして、このコード:

class SomeClass {
    public static synchronized void setLastAccess(Date date) {
    }
}

以下と同じです:

class SomeClass {
    public static void setLastAccess(Date date) {
        synchronized(SomeClass.class) {
        }
    }
}
于 2011-10-18T18:13:56.970 に答える
0

同期メソッドがインスタンスメソッドの場合、ロックは各オブジェクトで行われます。したがって、2つのオブジェクトobj1とobj2がある場合、それらは独自のインスタンスをロックした状態でメソッドを実行できます。

静的メソッドが同期されている場合、ロックはクラスオブジェクトに対して行われます。そのため、最初の静的同期メソッドが実行されるときに、そのメソッドおよびその他の静的メソッドを実行することはできません。

于 2011-10-18T19:09:30.047 に答える