java设计模式--单例

GOF23(group of four)---由4个大牛总结的JAVA23种常用的设计模式,归根结底都是为了代码的可扩展性。

设计模式中一种比较重要的思想就是:开闭原则,尽量做到对扩展开放,对修改关闭。


单例模式:开发中最常见也是最简单的一种模式

单例模式确保某个类只有一个实例,而且自行实例化并向整个系统提供这个实例。在计算机系统中,线程池、缓存、日志对象、对话框、打印机、显卡的驱动程序对象常被设计成单例。

1.懒汉式单例

//懒汉式单例类.在第一次调用的时候实例化自己,优点:延时加载,用到时候才NEW,缺点:方法是同步的,多线程调用时,需要等待锁,所以效率低

public class Singleton {  
    private Singleton() {}  
    private static Singleton single=null;  
    //静态工厂方法   
    public static synchronized  Singleton getInstance() {  
         if (single == null) {    
             single = new Singleton();  
         }    
        return single;  
    }  
}  

懒汉式单例双重检查

public class Singleton {  
    private Singleton() {}  
    private static Singleton single=null;  
    //静态工厂方法   
    public static Singleton getInstance() {  
if(single == null){
synchronized(Singleton.class){
if (single == null) {
single = new Singleton();
}
}

} return single; } }

2.恶汉式单例 ---初始化时就创建对象,优点:执行效率高,缺点:一开始就创建对象,比较浪费

//饿汉式单例类.在类初始化时,已经自行实例化   
public class Singleton1 {  
    private Singleton1() {}  
    private static final Singleton1 single = new Singleton1();  
    //静态工厂方法   
    public static Singleton1 getInstance() {  
        return single;  
    }  
} 

3.静态内部类模式  比以上都要好  

public class Singleton {    
    private static class LazyHolder {    
       private static final Singleton INSTANCE = new Singleton();    
    }    
    private Singleton (){}    
    public static final Singleton getInstance() {    
       return LazyHolder.INSTANCE;    
    }    
}  

4.枚举单例   不会被反序列化,或反编译,执行效率也比较高

public enum MeijuDl {
    //本身就是单例的
    INSTATCE;
    public void fangfa(){
    }
    
    public static void main(String[] args) {
        MeijuDl.INSTATCE.fangfa();
    }

}

以上几种方法都是线程安全的

测试方法

public class TestXiaolv {
    
    public static void main(String[] args) throws InterruptedException {
        
        //线程计数器
        final CountDownLatch countDownLatch = new CountDownLatch(10);
        long t1 = System.currentTimeMillis();
        
        for (int i = 0; i < 10; i++) {
            new Thread(new Runnable() {
                public void run() {
                    for (int i = 0; i < 100000; i++) {
                        Object o = LanhanDL.getInstance();
                    }
                    countDownLatch.countDown();
                    
                }
            }).start();
        }
        
        countDownLatch.await();
        
        long t2 = System.currentTimeMillis();
        System.out.println(t2-t1);
        
        
    }
}
原文地址:https://www.cnblogs.com/jentary/p/5905673.html