静态同步方法java

时间:2016-06-14 18:23:23

标签: java multithreading

以下代码给出固定输出为400000000,而当我从同步addOne方法中删除静态关键字时,我得到随机输出任意小于400000000的整数。
任何人都可以解释一下吗?

public class ThreadTest extends Thread{

public static int sharedVar = 0;

private static synchronized void addOne()
{
    for (int i = 0; i < 200000000; i++)
    {
        sharedVar++;
    }
}

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

public static void main(String[] args)
{
    ThreadTest mt1 = new ThreadTest();
    ThreadTest mt2 = new ThreadTest();
    try
    {
        // wait for the threads
        mt1.start();
        mt2.start();    
        mt1.join();
        mt2.join();
        System.out.println(sharedVar);
    }
    catch (InterruptedException e1)
    {
        e1.printStackTrace();
    }
}
}

2 个答案:

答案 0 :(得分:0)

稍微更改您的addOne()方法,如下所示,了解行为。

private static synchronized void addOne() {
    for (int i = 0; i < 5; i++) {
        sharedVar++;
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
        }
        System.out.println(Thread.currentThread().getName());
    }
}
带有static

输出为:

Thread-0
Thread-0
Thread-0
Thread-0
Thread-0
Thread-1
Thread-1
Thread-1
Thread-1
Thread-1

没有static输出是:

Thread-0
Thread-1
Thread-0
Thread-1
Thread-0
Thread-1
Thread-1
Thread-0
Thread-0
Thread-1

如果您需要了解更多信息,请参阅oracle thread synchronization tutorial

答案 1 :(得分:0)

当方法为static时,它基本上属于类定义;因此,当该类的多个实例调用该方法时,它们都指向一个static表示。当它不是static时,考虑属于该类的所有单个实例的方法是有用的。

就您的应用而言,当方法不是static时,您只需synchronize实例的方法,而不是'共享'方法。在运行Thread时,他们都发现他们可以立即访问两个方法,因为您只能在运行时实例上实现同步。在这方面,如果您想从同一个实例上的不同addOne()拨打Thread阻止竞争条件。但是在您的应用程序中,您尝试沿全局变量而不是运行时实例的成员进行同步,因此该方法应该保留static,或者您的共享数据应该移动到可能是{{的共享对象1}} on。