Kum*_*lok 0 java multithreading synchronized race-condition
我试图理解Java中的Synchornized.我知道如果我从2个不同的线程访问同一个对象的同步方法,一次只能有一个访问.
但我认为如果在2个不同的实例上调用相同的方法,则两个对象都应该能够并行访问该方法.如果从方法访问/修改静态成员变量,这将导致竞争条件.但我无法在下面的代码中看到竞争状况.
有人可以解释一下代码或我的理解是否错误.
有关参考代码,请访问:http://ideone.com/wo6h4R
class MyClass
{
public static int count=0;
public int getCount()
{
System.out.println("Inside getcount()");
return count;
}
public synchronized void incrementCount()
{
count=count+1;
}
}
class Ideone
{
public static void main(String[] args) throws InterruptedException {
final MyClass test1 = new MyClass();
final MyClass test2 = new MyClass();
Thread t1 = new Thread() {
public void run()
{
int k=0;
while (k++<50000000)
{
test1.incrementCount();
}
}
};
Thread t2 = new Thread() {
public void run()
{
int l=0;
while (l++<50000000)
{
test2.incrementCount();
}
}
};
t1.start();
t2.start();
t1.join();
t2.join();
//System.out.println(t2.getState());
int x=500000000+500000000;
System.out.println(x);
System.out.println("count = " + MyClass.count);
}
Run Code Online (Sandbox Code Playgroud)
}
你是对的,存在竞争条件.但是这些活动非常快,以至于它们不太可能发生 - 并且synchronized关键字可能提供同步"帮助",虽然JLS没有要求,但隐藏了比赛.
如果你想让它变得更加明显,你可以"拼出" count = count + 1代码并进入睡眠状态:
public synchronized void incrementCount()
{
int tmp = count + 1;
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
count=tmp;
}
Run Code Online (Sandbox Code Playgroud)
这应该更容易显示比赛.(我对中断异常的处理不利于生产代码,顺便说一下;但对于像这样的小型测试应用来说,这已经足够了.)
这里学到的教训是:竞争条件可能很难通过测试,因此最好真正理解代码并向自己证明这是正确的.