大家可以看到在PairManagerCriticalSetion类的同步块必须在指定一个对象后才会进行同步,还有在PairMangerMethod类里我们覆盖了PairManager类里的doTask方法并且在覆盖的新方法前加上了synchronized关键字,这就说明java里父类的方法被子类覆盖或者是接口的方法被实现,如果原方法没有synchronized关键字,实现方法可以加上,这种做法是java语言可以接受的。
大家在看看下面的例子,在这个例子里我们混合使用了两种同步方式:
package cn.com.sxia;
class DualSynch{
private Object syncObject = new Object();
public synchronized void f(){
System.out.println("Inside f()");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("Leaving f()");
}
public void g(){
synchronized (syncObject) {
System.out.println("Inside g()");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("Leaving g()");
}
}
}
public class SyncObject {
public static void main(String[] args) {
final DualSynch ds = new DualSynch();
new Thread(){
public void run(){
ds.f();
}
}.start();
ds.g();
}
}
结果如下:
Inside g()
Inside f()
Leaving f()
Leaving g()
我们不断运行这个main函数发现结果正常,表明两个同步方式可以混合使用,两种方式混合使用不会产生线程冲突。
同步块比起方法的同步还有一个优势,大家回到我们写的CriticalSection类,我们再看看结果:
pm1:PairManipulator [pm=Pair [x=680723, y=680723], checkCounter=671226]
pm2:PairManipulator [pm=Pair [x=627127, y=627127], checkCounter=1276546]
多次运行后同步块的结果记录的值都比同步方法大,这说明了同步块的方式让对象不加锁的时间更长,这就说明使用同步块进行线程同步时候,其他的线程能得到更多的访问资源的机会,这个特别可能会是编程的一大优势,大家可以记下来,说不定会用上啊。