GOF23的一些总结(一)

1、单利模式:
核心作用:保证一个类中只有一个实例(对象),并且提供一个访问该实例的全局访问点。(不管你启动了多少个,始终只有一个)
比如windows的TaskManager,Recycle Bean。
优点:单利只生成一个实例,减少了系统性能的开销,减少系统性能开销。可以在系统设置全局访问点,优化共享资源访问。
常见的五种单利模式实现方式:
主要:
饿汉式:(线程安全,调用效率高。但是,不能延时加载。)
懒汉式:(线程安全,调用效率不高,但是,可以延时加载。)
-其他:
双重检测锁式(由于JVM低层内部模型原因,偶尔会出问题。不建议使用)
静态内部类式(线程安全,调用效率高。但是,可能延时加载)
枚举单例(线程安全,调用效率高,不能延时加载)
饿汉式

public class SingletonHungry{
    private static /*final*/ SingletonHungry instance = new SingletonHungry();//类初始化的时候加载(没有延时)
    private SingletonHungry(){
    }
    //类加载器加载时本身线程安全。
    public static SingletonHungry getInstance(){
                return instance;
    }
}

懒汉式

public class SingletonLazzy{
    //类初始化的时候不实例化对象
    private static SingletonLazzy instance;
    //私有化构造方法
    private SingletonLazzy(){
    }
    //方法同步,调用效率低
    private static synchronized SingletonLazzy getInstance(){
        if(instance==null){
            instance=new SingletonLazzy;
        }
        return instance;
    }
}

双重检测锁机制

//由于类加载和JVM会调整顺序,所以仅做参考
public class SingletonCheck{
    private static SingletonCheck instance=null;
    public static SingletonCheck getInstance(){
            if(null==instance){
                SingletonCheck sc;
                    synchronized (SingletonCheck.class){
                    sc=instance;
                        if(null=sc){
                            synchronized(SingletonCheck.class){
                                if(sc==null){
                                    sc=new SingletonCheck();
                                }
                            }
                            instance=sc;
                        }
                }
            }
            return instance;
        }
    private SingletonCheck(){

    }
}

静态内部类实现方式

//线程安全,调用效率高,并且实现了延时加载
public class SingletonStaticInnerClass{

private static class SingletonClassInstance{
    private static final SingletonStaticInnerClass instance = new SingletonstaticInnerClass();
}

private static SingletonStaticInnerClass getInstanc(){
    return SingletonClassInstance.instance;
}

private SingletonStaticInnerClass(){
}

}

通过枚举实现单利模式

//避免了反射和序列化的漏洞,调用效率比较高,没有懒加载
public enum SingletonEnum{
    //这个枚举,本身就是单利模式
    INSTANCE;
    //添加自己需要的操作
    public void  singletonOpreation(){
    }
}

测试反射和反序列化破解(除枚举外的)单利模式

public class Client{
    public sttic void main (String[]args){
        Class<Singleton> clazz=(Class<Singleton>)Class.forName("");
        Constructor<Singleton> c = clazz.getDeclaredConstructor(null);
        c.setAccessible(true);//跳过检测
        Singleton s3 = c.newInstance();
    }
}

反破解跳过(除枚举外的其中饿汉式)私有权限检测方式

public class Singleton{

    private static Singleton instance =new Singleton();

    private Singleton(){//破解反射
        if(null!=instance){
            throw new RunTimeException();
        }
    }

    public static Singleton getInstance(){
        return instance;
    }
}

测试反序列化破解序列化的单利

public class Client2{
    public static void main (String[]args){
        Singleton s1 = Singleton.getInstance();
        try{
        FileOutputStream fos =new FileOutputStream("d:/a.txt");
        ObjectOutputStream oos = new ObjectOutputStream(fos);
        oos.writeObjec(s1);
        }catch{
            e.printlnStackException();
        }finally{
            oos.close();
            fos.close();
        }
        ObjectInputStream ois  = new ObjectInputStream(new FileInputStream("d:/a.txt"));
            Singleton s3=(Singleton)ois.readObject();
            System.out.println(s3);
    }
}

序列化的单利

public class Singleton implements Serialzable{

    private static Singleton instance =new Singleton();

    private Singleton(){//破解反射
        if(null!=instance){
            throw new RunTimeException();
        }
    }

    public static Singleton getInstance(){
        return instance;
    }
    //破解反序列化,这个方法是如果已经有对象了,再调用的时候把原来的调回去,不用再给创建新的对象
    private Object readResolve()throws ObjectStreamException{
        return instance;
    }
}

相对环境测试效率

import java.util.concurrent.CountDownLatch;

/**
 * 相对环境下多线程并发测试单利运行效率
 * @author Administrator
 *
 */
public class Test2 {

    public static void main(String[] args) throws InterruptedException {
        long start =System.currentTimeMillis();
        int threadNum=10;
        final CountDownLatch countDownLatch = new CountDownLatch(threadNum);
        for(int i=0;i<threadNum;i++){
            new Thread(new Runnable(){
                @Override
                public void run() {
                    for(int i=0;i<1000000;i++){
                        Object o = Singleton.getInstance();
                        //Object o =Singleton.INSTANCE; 
                    }
                    countDownLatch.countDown();
                }

            }).start();

        }

        countDownLatch.await();

        long end =System.currentTimeMillis();
        System.out.println("总耗时:"+(end-start));
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值