设计模式之-单例模式

设计模式之-单例模式,第1张

设计模式之-单例模式 1.单利 sigleton
  • 1.各种mgr
  • 2.各种Factory
使用:
1.私有化对象
2.私有化构造器
3.公有化获取对象方法
第一种:推荐使用,线程安全:
  • 类加载到内存之后,就实例化一个单利,JVM保证线程安全;
  • 缺点:类装载时候就会实例化
package com.fengzi.design;


public class Mgr01 {

    private static Mgr01 mgr01 = new Mgr01();

    private Mgr01(){}

    public static Mgr01 getInstance(){
        return mgr01;
    }


    public static void main(String[] args) {
        System.out.println(Mgr01.getInstance());
        System.out.println(Mgr01.getInstance());
    }
}

2.lazy loading 懒汉式
  • 多线程情况下会产生多个实例
package com.fengzi.design;


public class Mgr02 {

    private static Mgr02 mgr02 ;

    private Mgr02(){}

    public static Mgr02 getInstance(){
        if(mgr02 == null){
            try {
                Thread.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            mgr02 = new Mgr02();
        }
        return mgr02;
    }


    public static void main(String[] args) {
        for(int i = 0; i< 100;i++){
            new Thread(()->{
                System.out.println(Mgr02.getInstance().hashCode());
            }).start();
        }
    }
}
3.lazy loading :加锁,但是性能换安全
package com.fengzi.design;


public class Mgr03 {

    private static Mgr03 mgr02 ;

    private Mgr03(){}

    public static synchronized Mgr03 getInstance(){
        if(mgr02 == null){
            try {
                Thread.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            mgr02 = new Mgr03();
        }
        return mgr02;
    }


    public static void main(String[] args) {
        for(int i = 0; i< 100;i++){
            new Thread(()->{
                System.out.println(Mgr03.getInstance().hashCode());
            }).start();
        }
    }
}

4.lazy loading:将锁更加的细微化,加锁到需要加锁的地方
  • 这种方案不可行,if判断对象多线程都会进来执行
package com.fengzi.design;


public class Mgr04 {

    private static Mgr04 mgr02;

    private Mgr04() {
    }

    public static Mgr04 getInstance() {
        if (mgr02 == null) {
            synchronized (Mgr04.class) {
                try {
                    Thread.sleep(1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                mgr02 = new Mgr04();
            }
        }
        return mgr02;
    }


    public static void main(String[] args) {
        for (int i = 0; i < 100; i++) {
            new Thread(() -> {
                System.out.println(Mgr04.getInstance().hashCode());
            }).start();
        }
    }
}

5.双重检查+sync = 安全
package com.fengzi.design;


public class Mgr05 {

    //防止指令重排
    private static volatile Mgr05 mgr02;

    private Mgr05() {
    }

    public static Mgr05 getInstance() {
        if (mgr02 == null) {
            synchronized (Mgr05.class) {
                if (mgr02 == null) {
                    try {
                        Thread.sleep(1);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    mgr02 = new Mgr05();
                }
            }
        }
        return mgr02;
    }


    public static void main(String[] args) {
        for (int i = 0; i < 100; i++) {
            new Thread(() -> {
                System.out.println(Mgr05.getInstance().hashCode());
            }).start();
        }
    }
}

6.静态内部类:推荐使用,比第一种更好一点
  • 静态内部类在外边类被加载的时候,是不会加载内部类
package com.fengzi.design;


public class Mgr06 {

    private Mgr06() {
    }

    private static class Mgr06Holder{
        private static final Mgr06 mgr06 = new Mgr06();
    }

    public static Mgr06 getInstance() {

        return Mgr06Holder.mgr06;
    }


    public static void main(String[] args) {
        for (int i = 0; i < 100; i++) {
            new Thread(() -> {
                System.out.println(Mgr06.getInstance().hashCode());
            }).start();
        }
    }
}

7.枚举类 : 完美中的完美
  • 不仅可以解决线程同步,还可以防止反序列化
package com.fengzi.design;


public enum Mgr07 {

    INSTANCE;

    public static void main(String[] args) {
        for (int i = 0; i < 100; i++) {
            new Thread(() -> {
                System.out.println(Mgr07.INSTANCE.hashCode());
            }).start();
        }
    }
}

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5683418.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存