首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > JAVA > J2SE开发 >

同步有关问题 thinking in java中的一段代码 不知怎么理解

2012-01-01 
同步问题 thinking in java中的一段代码不知如何理解P494同步控制块必须指定一个对象才能进行同步,通常,最

同步问题 thinking in java中的一段代码 不知如何理解
P494
同步控制块必须指定一个对象才能进行同步,通常,最合理的对象就是在其上调用方法的当前对象:   synchronized(this),在PairManager2中采用了这种方法。这样,当为同步控制块请求锁的时候,对象的其它同步控制方法就不能被调用了。所以其效
果不过是缩小了同步控制的范围。

但是随后就给了一段代码:  

//:   c13:SyncObject.java
//   Synchronizing   on   another   object
//   From   'Thinking   in   Java,   3rd   ed. '   (c)   Bruce   Eckel   2002
//   www.BruceEckel.com.   See   copyright   notice   in   CopyRight.txt.
import   com.bruceeckel.simpletest.*;

class   DualSynch   {
    private   Object   syncObject   =   new   Object();
    public   synchronized   void   f()   {
        System.out.println( "Inside   f() ");
        //   Doesn 't   release   lock:
        try   {
            Thread.sleep(500);
        }   catch(InterruptedException   e)   {
            throw   new   RuntimeException(e);
        }
        System.out.println( "Leaving   f() ");
    }
    public   void   g()   {
        synchronized(syncObject)   {
            System.out.println( "Inside   g() ");
            try   {
                Thread.sleep(500);
            }   catch(InterruptedException   e)   {
                throw   new   RuntimeException(e);
            }
            System.out.println( "Leaving   g() ");
        }
    }
}

public   class   SyncObject   {
    private   static   Test   monitor   =   new   Test();
    public   static   void   main(String[]   args)   {
        final   DualSynch   ds   =   new   DualSynch();
        new   Thread()   {
            public   void   run()   {
                ds.f();
            }
        }.start();
        ds.g();
        monitor.expect(new   String[]   {
            "Inside   g() ",
            "Inside   f() ",
            "Leaving   g() ",
            "Leaving   f() "
        },   Test.WAIT   +   Test.IGNORE_ORDER);
    }
}   ///:~

这里两种同步方法都用到了   但结果并不是     "这样,当为同步控制块请求锁的时候,对象的其它同步控制方法就不能被调用了 "

第一段文字针对的是下面的代码:
//:   c13:CriticalSection.java
//   Synchronizing   blocks   instead   of   entire   methods.   Also
//   demonstrates   protection   of   a   non-thread-safe   class


//   with   a   thread-safe   one.
//   From   'Thinking   in   Java,   3rd   ed. '   (c)   Bruce   Eckel   2002
//   www.BruceEckel.com.   See   copyright   notice   in   CopyRight.txt.
import   java.util.*;

class   Pair   {   //   Not   thread-safe
    private   int   x,   y;
    public   Pair(int   x,   int   y)   {
        this.x   =   x;
        this.y   =   y;
    }
    public   Pair()   {   this(0,   0);   }
    public   int   getX()   {   return   x;   }
    public   int   getY()   {   return   y;   }
    public   void   incrementX()   {   x++;   }
    public   void   incrementY()   {   y++;   }
    public   String   toString()   {
        return   "x:   "   +   x   +   ",   y:   "   +   y;
    }
    public   class   PairValuesNotEqualException
    extends   RuntimeException   {
        public   PairValuesNotEqualException()   {
            super( "Pair   values   not   equal:   "   +   Pair.this);
        }
    }
    //   Arbitrary   invariant   --   both   variables   must   be   equal:
    public   void   checkState()   {
        if(x   !=   y)
            throw   new   PairValuesNotEqualException();
    }
}

//   Protect   a   Pair   inside   a   thread-safe   class:
abstract   class   PairManager   {
    protected   Pair   p   =   new   Pair();
    private   List   storage   =   new   ArrayList();
    public   synchronized   Pair   getPair()   {
        //   Make   a   copy   to   keep   the   original   safe:
        return   new   Pair(p.getX(),   p.getY());
    }
    protected   void   store()   {   storage.add(getPair());   }
    //   A   "template   method ":
    public   abstract   void   doTask();
}

//   Synchronize   the   entire   method:
class   PairManager1   extends   PairManager   {
    public   synchronized   void   doTask()   {
        p.incrementX();
        p.incrementY();
        store();
    }
}

//   Use   a   critical   section:
class   PairManager2   extends   PairManager   {
    public   void   doTask()   {
        synchronized(this)   {
            p.incrementX();
            p.incrementY();


        }
        store();
    }
}

class   PairManipulator   extends   Thread   {
    private   PairManager   pm;
    private   int   checkCounter   =   0;
    private   class   PairChecker   extends   Thread   {
        PairChecker()   {   start();   }
        public   void   run()   {
            while(true)   {
                checkCounter++;
                pm.getPair().checkState();
            }
        }
    }
    public   PairManipulator(PairManager   pm)   {
        this.pm   =   pm;
        start();
        new   PairChecker();
    }
    public   void   run()   {
        while(true)   {
            pm.doTask();
        }
    }
    public   String   toString()   {
        return   "Pair:   "   +   pm.getPair()   +
            "   checkCounter   =   "   +   checkCounter;
    }
}

public   class   CriticalSection   {
    public   static   void   main(String[]   args)   {
        //   Test   the   two   different   approaches:
        final   PairManipulator
            pm1   =   new   PairManipulator(new   PairManager1()),
            pm2   =   new   PairManipulator(new   PairManager2());
        new   Timer(true).schedule(new   TimerTask()   {
            public   void   run()   {
                System.out.println( "pm1:   "   +   pm1);
                System.out.println( "pm2:   "   +   pm2);
                System.exit(0);
            }
        },   500);   //   run()   after   500   milliseconds
    }
}   ///:~


请问   第一段文字如何理解   ??   谢谢   !

[解决办法]
帮顶
[解决办法]
不清楚楼主是哪里不明白,synchronized 字段可以加在方法前面如
public synchronized void get(){
.......
}
就相当于
public void get(){
synchronized(this){
.......
}
}
楼主贴出的上半段代码f()和g()虽然都有synchronized 字段,但是两者加锁的对象却不一致,一个是this,而另一个是syncObject ;这两个方法当然不会造成互斥访问了

热点排行