java – 同步方法无法按预期工作

我有一个由两个线程共享的变量.这两个线程将对它进行一些操作.我不知道为什么每次执行程序时sharedVar的结果都不同.

public class Main
{
    public static int sharedVar = 0;
    public static void main(String[] args) 
    {
        MyThread mt1 = new MyThread();
        MyThread mt2 = new MyThread();
        mt1.start();
        mt2.start();

        try
        {
            // wait for the threads
            mt1.join();
            mt2.join();
        }
        catch (InterruptedException e1)
        {
            e1.printStackTrace();
        }

        System.out.println(sharedInt); // I expect this value to be 20000, but it's not
    }
}

以下是“MyThread”类

public class MyThread extends Thread
{
    private int times = 10000;
    private synchronized void addOne()
    {
        for (int i = 0; i < times; ++i)
        {
            Main.sharedVar ++;
        }
    }

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

sharedVar的最终结果有时是13735,12508或18793;但从来没有20000,这是我期望的结果.该计划的另一个有趣的事情是时间= 1000.我总是得到2000作为最终结果.

谁能解释这个现象?

synchronized方法保护资源,这意味着您的代码等效于:

private void addOne()
{
    synchronized(this)
    {
        for (int i = 0; i < times; ++i)
        {
            Main.sharedVar ++;
        }
    }
}

但是您有2个对象,其中调用了addOne方法.这意味着mt1.addOne的这个与mt2.addOne不同,因此你没有共同的公共资源.

尝试将addOne代码更改为:

private void addOne()
{
    synchronized(MyThread.class)
    {
        for (int i = 0; i < times; ++i)
        {
            Main.sharedVar ++;
        }
    }
}

你会观察到预期的行为.正如下面的注释所示,最好使用与MyThread.class不同的对象进行同步,因为类对象可以从许多点访问,而其他代码很容易尝试使用同一个对象进行同步.

相关文章
相关标签/搜索