代码之家  ›  专栏  ›  技术社区  ›  Summer_More_More_Tea

如何在java中同步静态方法

  •  8
  • Summer_More_More_Tea  · 技术社区  · 15 年前

    我在Java中实现单例模式时遇到了这个问题。尽管下面列出的示例不是我真正的代码,但是与原来的非常相似。

    public class ConnectionFactory{
        private static ConnectionFactory instance;
    
        public static synchronized ConnectionFactory getInstance(){
            if( instance == null ){
                instance = new ConnectionFactory();
            }
    
            return instance;
        }
    
        private ConnectionFactory(){
            // private constructor implementation
        }
    }
    

    我说得对吗?或者JVM使用其他机制来实现静态同步方法?如果我必须在一个类中实现多个静态同步方法,那么最佳实践是什么?

    5 回复  |  直到 9 年前
        1
  •  7
  •   Community CDub    8 年前

    最好的方法(尽可能少地修改代码)是这样做:

    public class ConnectionFactory{
        private static ConnectionFactory instance = new ConnectionFactory();
    
        public static ConnectionFactory getInstance(){
            return instance;
        }
    
        private ConnectionFactory(){
        }
    }
    

    正如你所看到的,没有真正的需要 getInstance

    public class ConnectionFactory{
        public static final ConnectionFactory INSTANCE = new ConnectionFactory();
    
        private ConnectionFactory(){
        }
    }
    

    UPD关于同步:最好的方法是在外部类看不到的锁上同步,即:

    public class ConnectionFactory{
        private static final Object lock = new Object();
    
        public static void doSmth() {
            synchronized (lock) {
    
               ...
            }
        }
    
        public static void doSmthElse() {
            synchronized (lock) {
    
               ...
            }
        }
    }
    

    this this one ),我认为在类上同步也是如此。

        2
  •  3
  •   Mark Pope    15 年前

    有几种方法可以创建单例。

    推荐的一种方法是使用枚举(保证只创建一个实例):

    public enum ConnectionFactory {
    
      INSTANCE;
    
    }
    

    也可以在类加载时静态创建:

    public class ConnectionFactory {
    
      private static ConnectionFactory INSTANCE = new ConnectionFactory();
    
      private ConnectionFactory() {}
    
      public static ConnectionFactory getInstance() {
        return INSTANCE;
      }    
    
    }
    

    如果您需要懒洋洋地加载它,您可以使用这个习惯用法(而不是 double checked locking anti-pattern )

    public class ConnectionFactory {
    
      private static class ConnectionFactoryHolder {
        private static ConnectionFactory INSTANCE = new ConnectionFactory();
      }
    
      public static ConnectionFactory getInstance() {
        return ConnectionFactoryHolder.INSTANCE;
      }
    
    }
    
        3
  •  2
  •   unbeli    15 年前

        4
  •  2
  •   Nathan Hughes    15 年前

    静态同步方法使用类上的锁。在您的示例中,它将访问ConnectionFactory类对象上的锁。最好的做法是不要把锁握得太久。是否有多个同步方法本身不是问题。

        5
  •  0
  •   Shikhar Mishra    15 年前

    通用程序设计 建议使用枚举创建单例。所以你的代码应该是这样的:

    public enum ConnectionFactory{
    INSTANCE;
    
    // Other factory methods go here.
    
    }