以下代码给出固定输出为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();
}
}
}
答案 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。