动力节点旗下在线教育品牌  |  咨询热线:400-8080-105 学Java全栈,上蛙课网
首页 > 文章

Java单例设计模式的理解与常规实现方式

08-07 21:00 1033浏览
举报 T字号
  • 大字
  • 中字
  • 小字

1:Java中单例模式是一种常见的设计模式,单例模式有以下特点:

      单例类只能有一个实例。

      单例类必须自己创建自己的唯一实例。 单例类必须给所有其他对象提供这一实例。

  单例模式确保某个类只有一个实例,而且自行实例化并向整个系统提供这个实例。

2:java中单例模式的写法也有很多种,我在这里列举几张常用的方式:

     1、饿汉式,线程安全 但效率比较低:

/** 
 * 单例模式的实现:饿汉式,线程安全 但效率比较低 
 */  
public class SingletonTest {  

    // 定义一个私有的构造方法
    private SingletonTest() {  
    }  

    // 将自身的实例对象设置为一个属性,并加上static和final修饰符
    private static final SingletonTest instance = new SingletonTest();  

    // 静态方法返回该类的实例
    public static SingletonTest getInstancei() {  
        return instance;  
    }  
  
}

     2、懒汉式,非线程安全:

/**  
 * 单例模式的实现:懒汉式,非线程安全   
 *   
 */  
public class SingletonTest {

    // 定义私有构造方法(防止通过 new SingletonTest()去实例化)
    private SingletonTest() {   
    }   

    // 定义一个SingletonTest类型的变量(不初始化,注意这里没有使用final关键字)
    private static SingletonTest instance;   

    // 定义一个静态的方法(调用时再初始化SingletonTest,但是多线程访问时,可能造成重复初始化问题)
    public static SingletonTest getInstance() {   
        if (instance == null)   
            instance = new SingletonTest();   
        return instance;   
    }   
}

     3、懒汉式,线程安全简单实现  :

/**  
 * 单例模式的实现:懒汉式,线程安全简单实现   
 *   
 */  
public class SingletonTest {

    // 定义私有构造方法(防止通过 new SingletonTest()去实例化)
    private SingletonTest() {   
    }   

    // 定义一个SingletonTest类型的变量(不初始化,注意这里没有使用final关键字)
    private static SingletonTest instance;   

    // 定义一个静态的方法(调用时再初始化SingletonTest,使用synchronized 避免多线程访问时,可能造成重的复初始化问题)
    public static synchronized  SingletonTest getInstance() {   
        if (instance == null)   
            instance = new SingletonTest();   
        return instance;   
    }   
}

 

     4、线程安全 并且效率高  单例模式最优方案

/**  
 * 单例模式最优方案
 * 线程安全  并且效率高  
 *  
 */  
public class SingletonTest { 

    // 定义一个私有构造方法
    private SingletonTest() { 
     
    }   
    //定义一个静态私有变量(不初始化,不使用final关键字,使用volatile保证了多线程访问时instance变量的可见性,避免了instance初始化时其他变量属性还没赋值完时,被另外线程调用)
    private static volatile SingletonTest instance;  

    //定义一个共有的静态方法,返回该类型实例
    public static SingletonTest getIstance() { 
        // 对象实例化时与否判断(不使用同步代码块,instance不等于null时,直接返回对象,提高运行效率)
        if (instance == null) {
            //同步代码块(对象未初始化时,使用同步代码块,保证多线程访问时对象在第一次创建后,不再重复被创建)
            synchronized (SingletonTest.class) {
                //未初始化,则初始instance变量
                if (instance == null) {
                    instance = new SingletonTest();   
                }   
            }   
        }   
        return instance;   
    }   
}

     5、静态内部类方式

/**
   * 静态内部类方式
   *
   */
 public class Singleton {  
     private static class SingletonTest {  
     private static final Singleton INSTANCE = new Singleton();  
     }  
     private Singleton (){}
     public static final Singleton getInstance() {  
         return SingletonTest.INSTANCE;  
     }  
 }

以上单例如设计模式即使有多重检查锁也可以通过反射破坏单例

   6、目前最为安全的实现单例的方法是通过内部静态enum的方法来实现,因为JVM会保证enum不能被反射并且构造器方法只执行一次,事例如下:

/**
 * 使用枚举的单例模式
 *
 * @author uu
 */
public class EnumSingleton{
    private EnumSingleton(){}
    public static EnumSingleton getInstance(){
        return Singleton.INSTANCE.getInstance();
    }
    
    private static enum Singleton{
        INSTANCE;
        
        private EnumSingleton singleton;
        //JVM会保证此方法绝对只调用一次
        private Singleton(){
            singleton = new EnumSingleton();
        }
        public EnumSingleton getInstance(){
            return singleton;
        }
    }

   public static void main(String[] args) {
    EnumSingleton obj0 = EnumSingleton.getInstance();
    EnumSingleton obj1 = EnumSingleton.getInstance();
    //输出结果:obj0==obj1?true
    System.out.println("obj0==obj1?" + (obj0==obj1));
  }
}

 

在此浅谈一下个人理解,希望对大家有所帮助。

 

2人推荐
共同学习,写下你的评论
0条评论
HelloWorld
程序员HelloWorld

11篇文章贡献50393字

作者相关文章更多>

推荐相关文章更多>

Java数据结构

HelloWorld10-31 08:24

浅谈MySQL中SQL优化的常用方法

军哥08-12 23:29

MyBatis开发框架的四大核心

IT逐梦者08-17 21:43

五分钟读懂UML类图

江湖人称小李白12-10 10:41

一次搞定continue,break和return

HelloWorld11-06 11:19

发评论

举报

0/150

取消