静态同步方法java

静态同步方法java,java,multithreading,Java,Multithreading,下面的代码给出了一个400000000的固定输出,而当我从synchronized addOne方法中删除static关键字时,我得到的是任何小于400000000的整数的随机输出。 谁能解释一下吗 public class ThreadTest extends Thread{ public static int sharedVar = 0; private static synchronized void addOne() { for (int i = 0; i < 2000

下面的代码给出了一个400000000的固定输出,而当我从synchronized addOne方法中删除static关键字时,我得到的是任何小于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();
    }
}
}
public类ThreadTest扩展线程{
公共静态int sharedVar=0;
私有静态同步的void addOne()
{
对于(int i=0;i<200000000;i++)
{
sharedVar++;
}
}
@凌驾
公开募捐
{
addOne();
}
公共静态void main(字符串[]args)
{
ThreadTest mt1=新的ThreadTest();
ThreadTest mt2=新的ThreadTest();
尝试
{
//等待线程
mt1.start();
mt2.start();
mt1.join();
mt2.join();
System.out.println(sharedVar);
}
捕捉(中断异常e1)
{
e1.printStackTrace();
}
}
}
稍微更改
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());
    }
}
没有
静态
时,输出为:

Thread-0
Thread-0
Thread-0
Thread-0
Thread-0
Thread-1
Thread-1
Thread-1
Thread-1
Thread-1
Thread-0
Thread-1
Thread-0
Thread-1
Thread-0
Thread-1
Thread-1
Thread-0
Thread-0
Thread-1
如果您需要了解更多信息,请参阅。

稍微更改
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());
    }
}
没有
静态
时,输出为:

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

如果您需要更多信息来理解它,那么请参考。

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


就您的应用程序而言,当方法不是静态的时,您只能沿着实例的方法而不是“共享”方法进行同步。当涉及到运行
线程时,它们都会发现它们可以立即访问各自的两个方法,因为您只能在运行时实例上实现同步。在这方面,如果您希望在同一实例上从不同的
线程调用
addOne()
,这将阻止竞争条件。但是,在应用程序中,您正试图沿着全局变量而不是运行时实例的成员进行同步,因此该方法应保持
静态
,或者您的共享数据应移动到一个共享对象,该共享对象可能是
同步的。

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

就您的应用程序而言,当方法不是静态的时,您只能沿着实例的方法而不是“共享”方法进行同步。当涉及到运行
线程时,它们都会发现它们可以立即访问各自的两个方法,因为您只能在运行时实例上实现同步。在这方面,如果您希望在同一实例上从不同的
线程调用
addOne()
,这将阻止竞争条件。但是,在应用程序中,您试图沿着全局变量而不是运行时实例的成员进行同步,因此该方法应该保持
静态
,或者您的共享数据应该移动到一个共享对象,该共享对象可以
同步

请参见