最近学习java的线程,如果构造方法是原子操作,为什么不能用synchronized直接实现方法的同步机制,而用同步代码块可以实现。如:class Test{
   private int sid;
   static int id = 0;
   public Test(){
     id++;
     sid = id; 
   }
}
如果两个线程同时调用构造对象,一个线程已执行完id++,然后时间片完了;而此时另一个线程也执行到了id++,时间片到了,
那么原先那个线程的sid的值就出现错误,
class Test{
   private int sid;
   static int id = 0;
   public synchronized Test(){ //这样做编译错误,为什么?????????????????????????????//
     id++;
     sid = id; 
   }
}

解决方案 »

  1.   

    构造函数不用synchronized是一个规定。
    因为一般来说,两个线程各自去new Test(),会生成两个对象。
    两个对象之间的同步是没用意义的。你上面的例子事实上会出现id相同的情况。
    改为public Test() {
         synchronized(this.getClass()){
         id = c;  
         c++;
         }
        }就可以了。注意是
    synchronized(this.getClass()),而不是synchronized(this).
    因为id是static,所以要锁住整个类。
      

  2.   

    在Java虚拟机上似乎构造方法是隐含同步的,所以不需要使用synchronized关键字。