Java使用线程对数组中的数字求和:在同步块中将新变量用作锁:区别

问题描述 投票:-1回答:1

我有一个使用线程求和的数字数组。为了避免出现竞争情况,将增加总和变量的代码块包装在synchronized中。最初,我将其包装在synchronized (this)中,但效果很好。

但是,我试图理解当this以外的内容作为锁定值传递时会发生什么。我试图将锁定锁定为synchronized (new Object()),以便每次执行时锁定值都不同。但是它仍然可以正常工作,尽管我希望它会中断,因为现在值-锁定对象的引用每次都会更改:

public class SumNumbersCommon {
    private static int totalSum;
    private static int[] numbers = new int[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

    public static void main(String[] args) throws  Exception  {
        System.out.printf("Usual sum: %,d\n", sum(numbers));

        int left = numbers.length / 2;
        Thread leftThread = new Thread(new SummerThread(0, left));
        Thread rightThread = new Thread(new SummerThread(left + 1, numbers.length - 1));

        leftThread.start();
        rightThread.start();

        leftThread.join();
        rightThread.join();

        System.out.printf("total sum: %,d\n", totalSum);

    }

    static class SummerThread implements Runnable  {
        private int min;
        private int max;

        public SummerThread(int min, int max)  {
            this.min = min;
            this.max = max;
        }

        @Override
        public void run() {
            for (int i = min; i <= max; i++)  {
                synchronized (new Object()) {
                    totalSum += numbers[i];
                }
            }
        }
    }

    public static int sum(int[] numbers)  {
        int result = 0;
        for (int n: numbers)  {
            result += n;
        }
        return result;
    }

}

为什么它仍然起作用?在哪种情况下,我会使用synchronized (this)以外的其他方式?

java multithreading locking locks
1个回答
3
投票

您的线程仅执行一些琐碎的计算,因此您没有机会观察数据竞争。如果线程运行时间更长,则应观察到不一致之处。

synchronized(this)将使用this上的监视器,因此将对this的任何其他同步块和所有同步方法进行序列化。在此特定示例中,synchronized(this)将毫无意义,因为两个线程的this将不同。您需要一个共享对象来锁定。

synchronized(obj)可用于以更细粒度的方式控制同步。它不会影响对象的所有同步方法,而只会影响使用obj作为锁定对象的同步块。例如,这可以用于仅修改对象状态的子集,或修改不属于对象状态的某些其他共享状态。

© www.soinside.com 2019 - 2024. All rights reserved.