4

同期を使用した単純なマルチスレッドテスト。「同期」されていれば、他のスレッドが待つだろうと思いました。私は何が欠けていますか?

public class MultithreadingCounter implements Runnable {

    static int count = 0;

    public static void main(String[] args) {
        int numThreads = 4;
        Thread[] threads = new Thread[numThreads];

        for (int i = 0; i < numThreads; i++)
            threads[i] = new Thread(new MultithreadingCounter(), i + "");

        for (int i = 0; i < numThreads; i++)
            threads[i].start();

        for (int i = 0; i < numThreads; i++)
            try {
                threads[i].join();
            } catch (Exception e) {
                e.printStackTrace();
            }
    }           

    @Override
    public void run() {
        increment();
    }

    public synchronized void increment(){
            System.out.print(Thread.currentThread().getName() + ": " + count + "\t");
            count++; // if I put this first or increment it directly in the print line, it works fine.
    }
}

私はこれが次のようなものを表示すると思いました:

0: 1    2: 0    1: 2    3: 3    

しかし、その実際の出力:

0: 0    2: 0    1: 0    3: 3    

そしてこのような他のバリエーション。順番にではなく、各増分(つまり、0、1、2、3)を表示する必要があります。

4

3 に答える 3

8

キーワードsynchronizedはインスタンスメソッドにあります。2つのスレッドがスレッドオブジェクトの1つのこのメソッドを同時に実行することはできません。しかし、それはあなたのコードが行うことではありません。各スレッドは、独自のインスタンスでメソッドを実行します。同期は、意図したとおりに実行されません。それがstatic方法であるならば、それはそうするでしょう。

于 2012-12-05T00:12:19.687 に答える
1

あなたのincrement方法は次のようになりますstatic

public static synchronized void increment() {

現在、各オブジェクトはその個々のインスタンスで同期されていますが、countは静的変数であるため、Classオブジェクト自体で同期する必要があります。

于 2012-12-05T00:15:47.510 に答える
0

同期キーワードをメソッドの前に使用すると、そのオブジェクトに関してのみ、一度に1つのスレッドでのみメソッドを実行できるようになります。他のオブジェクトからのスレッドセーフを保証するものではありません。

于 2012-12-05T07:01:33.213 に答える