4

これは、Herbert Schildt の Java Fundamentals からの同期を示すプログラムです。メソッドsumArray(int[])synchronizedであり、プログラムが正しく動作するための要件です。ただし、synchronizedキーワードを削除すると、予想外に、プログラムはほぼ同じ出力を示し、それでも正しい結果が得られました。これがプログラムです。

class SumArray {
        private int sum;

        int sumArray(int[] nums) {
            sum = 0; // Reset sum.
            for(int i = 0; i < nums.length; i++) {
                sum += nums[i];
                System.out.println("Running total for " + Thread.currentThread().getName() + " is " + sum);
            }
            return sum;
        }
    }

    class SumThread implements Runnable {
        static SumArray sa = new SumArray();
        Thread thrd;
        int[] a;
        int answer;

        public SumThread(String name, int[] nums) {
            thrd = new Thread(this, name);
            a = nums;
            thrd.start();

        }

        @Override public void run() {
            System.out.println(thrd.getName() + " starting.");
            answer = sa.sumArray(a);
            System.out.println("Sum for " + thrd.getName() + " is " + answer);
            System.out.println(thrd.getName() + " terminating.");
        }

    }

    public class SyncExample {

        public static void main(String[] args) {
            int[] a = new int[] {1, 2, 3, 4, 5, 6};

            SumThread mt1 = new SumThread("Thread #1", a);
            SumThread mt2 = new SumThread("Thread #2", a);

            try {
                mt1.thrd.join();
                mt2.thrd.join();
            } catch(InterruptedException e) {
                e.printStackTrace();
            }
        }

    }

出力。

Thread #1 starting.
Running total for Thread #1 is 1
Running total for Thread #1 is 3
Running total for Thread #1 is 6
Running total for Thread #1 is 10
Running total for Thread #1 is 15
Running total for Thread #1 is 21
Sum for Thread #1 is 21
Thread #1 terminating.
Thread #2 starting.
Running total for Thread #2 is 1
Running total for Thread #2 is 3
Running total for Thread #2 is 6
Running total for Thread #2 is 10
Running total for Thread #2 is 15
Running total for Thread #2 is 21
Sum for Thread #2 is 21
Thread #2 terminating.

私のコンピューターに何か問題があるのでしょうか、それともスレッドがこれほど奇妙なものになっているのでしょうか?

4

2 に答える 2

6

問題は、配列が非常に小さいことですint[] a = new int[] {1, 2, 3, 4, 5, 6};

スレッド 1 は、スレッド 2 が開始する前に終了します。

10000 個以上の要素の配列で実行しようとすると、違いがわかる場合があります。

私はあなたのコードを10000要素で実行しました:

スレッド #1 を開始します。

スレッド #2 を開始します。

スレッド #1 の累計は 1 です

スレッド #2 の累計は 1 です

スレッド #1 の累計は 3 です

スレッド #2 の累計は 5 です

スレッド #2 の累計は 11 です

スレッド #2 の累計は 15 です

スレッド #1 の現在の合計は 8 です

..........

したがって、あなたのマシンがスレッドが順次実行されていることを示していたとしても、すべてのマシンおよびすべてのプログラムの起動でこのようになるという保証はありません。

また、この方法でもう 1 つの間違いが見つかりました。

編集

実際にはローカル変数であるはずのフィールドとして sum を宣言しました。私の出力で、これが計算にどのように影響するかを確認できます (あるスレッドの合計が別のスレッドによって変更されるなど)。

于 2013-07-06T09:21:22.963 に答える