大家都知道,java静态方法只初始化一次,我在想一个问题,既然就初始化一次,在进行并行操作的时候会不会有“同步问题”哦,请大家帮我解释下哦

解决方案 »

  1.   

    大家看下
    public class Singleton {
    private Singleton(){}
          //在自己内部定义自己一个实例,是不是很奇怪?
          //注意这是private 只供内部调用
          private static Singleton instance = new Singleton();
          //这里提供了一个供外部访问本class的静态方法,可以直接访问  
          public static Singleton getInstance() {
            return instance;   
          } 
        }   
        第二种形式: public class Singleton { 
      private static Singleton instance = null;
      public static synchronized Singleton getInstance() {
      //这个方法比上面有所改进,不用每次都进行生成对象,只是第一次     
      //使用时生成实例,提高了效率!
      if (instance==null)
        instance=new Singleton();
    return instance;   } 
    }  我个人认为,第一种的单体模式在多线程下有同步问题,不知道大家怎么看?
      

  2.   

    第二种有问题,
    synchronized(Singleton.class){
       if(instance == null){
          synchronized(Singleton.class){
              if(instance == null){
                  instance = new Singleton ();
              }
          }
       }
    }
      

  3.   

    第一种形式没线程问题是因为类成员instance在首次加载时就实例化好了吧,也就是说不是上面红色注释中说明的“每次都进行生成对象”?但是不是很清楚有没可能多个线程同时“首次”加载这种情况,这点望了解的兄弟说明一下。
    第二种形式有synchronized关键字,就消除了同步问题。7楼说有问题,详细说说你的看法,谢了。
      

  4.   

    答:我的意思是说:第一种没有问题。不需要加synchronized.而第二种有读/写冲突可能(或可能生成多个对象),因而必需要加synchronized。若已经加了,就正确了。
    另外,“但是不是很清楚有没可能多个线程同时“首次”加载这种情况,这点望了解的兄弟说明一下。 

    对于这一点,JLS中讲得很清楚:类的初始化过程,是JVM自动保证同步化了。因此:你的“可能多个线程同时“首次”加载这种情况”担心是多余的。
      

  5.   

    static与synchronized没有联系,这就是说,static的方法一样会出现同步的问题,但同步的问题只是发生在对同一资源有改变操作的情况下,如果这种操作没有任何改变,只是像7楼所说的读操作一样。那么即使加与不加synchronized也没有什么不一样
      

  6.   

    同步问题的重点在于读写操作,而不在于初始化。所以,即使是static,如果进行了读写操作,同样存在同步的问题。
      

  7.   

    我觉得同步是在多线程程序中才会有的,且同步的是临界资源。
    如果不是多线程的程序,那完全没必要考虑同步问题。
    如果是多线程的程序,就当前第一个类中的声明,虽然是静态方法,但没有用synchronized关键字,同样会有同步问题。
    参考线程相关书籍就能很快明白咯(*^__^*)
      

  8.   

    java的static方法怎么都扯到synchronized,
    一般做为static的方法都是些工具类的方法,只要里面没有带属性的static的变量就不会有同步的问题。
    比如
    public static insert(String sql){
        Dao.executeSql(sql);
    }
      

  9.   

    同步和Static没有必然的联系,变量在多线程中都可能存在同步问题,楼主需要好好理解一下同步的概念。
      

  10.   

    晕:害人不浅啊!啥叫初始化,就是类从磁盘装载之后,jvm自动调用的东西,在初始化完成之前,这个类是不能被应用使用的。
    当然,jvm也绝对不会把一个类装载并初始化多次。 
    所以,静态初始化的那部分代码,是永远没有什么同步问题。
      

  11.   

    楼主可以看看java的24种模式中的单例模式 也许能够解决你的问题
      

  12.   

    11 楼说的准确。类的初始化是 VM 保证同步的,所以使用第一种方法最简单,特别是这个 instance 并不是占用吓人的内存用量的时候。用空间换时间这时候非常地划算的。