单例模式

所谓单例模式就是:
a、只能有一个实例(构造私有化)
b、单例类必须自己创建自己的实例
c、单例类必须给他类提供这一个实例(提供实例化的静态方法)

1.1 饿汉式一:

public class Singleton {
    private Singleton() {

    }
    //这里必须静态修饰,否则 getInstance()方法中 return不了singleton
    private static Singleton singleton = new Singleton();

    public static Singleton getInstance() {

        return singleton;
    }

}

1.2 饿汉式二:

public class Singleton {
    private Singleton() {

    }
    private static Singleton singleton ;

    static {
        singleton = new Singleton();
    }
    public static Singleton getInstance() {

        return singleton;
    }

}

饿汉式单例在类加载初始化时候就创建好一个静态实例给外部使用,除非系统重启,否则这个实例是不会变的,所以本身是线程安全的

2.1、懒汉式

public class Singleton {
    private Singleton() {

    }
    private  static  Singleton singleton;
    
    public static Singleton getInstance() {
        if (singleton == null) {
            singleton = new Singleton();
        }
        return singleton;
    }

}

懒汉式单例由于延迟加载,所以在多线程环境,可能会出现非单例,不是多线程 环境则无此问题

2.2、验证懒汉式单例在多线程环境下出现的非单例情况
测试类:

public class Test {
    public static void main(String[] args) {
        //线程一
        new Thread(){
            @Override
            public void run() {
                System.out.println(Singleton.getInstance());
            }
        }.start();
        //线程二
        new Thread(){
            @Override
            public void run() {
                System.out.println(Singleton.getInstance());
            }
        }.start();
    }
}

在懒汉式单例中,设置休眠

public class Singleton {
    private Singleton() {

    }
    private  static  Singleton singleton;

    public static Singleton getInstance() {
        if (singleton == null) {
            try {
                Thread.sleep(10);//设置休眠
            } catch (Exception e) {
                e.printStackTrace();
            }
            singleton = new Singleton();
        }
        return singleton;
    }

}

运行测试类可以看到,多线程环境下出现的非单例情况:
在这里插入图片描述
2.3、改进懒汉式单例,使其在多线程环境下也不出现非单例情况
解决方式加同步锁:

public class Singleton {
    private Singleton() {

    }
    private  static  Singleton singleton;
	//加同步锁
   synchronized  public static Singleton getInstance() {
        if (singleton == null) {
            try {
                Thread.sleep(10);
            } catch (Exception e) {
                e.printStackTrace();
            }
            singleton = new Singleton();
        }
        return singleton;
    }

}
public class Singleton {
    private Singleton() {

    }
    private  static  Singleton singleton;

     public static Singleton getInstance() {
         synchronized(Singleton.class){//同步锁加在这里也可
             if (singleton == null) {
                 try {
                     Thread.sleep(10);
                 } catch (Exception e) {
                     e.printStackTrace();
                 }
                 singleton = new Singleton();
             }
         }
         return singleton;
    }

}

3.1、使用内部类实现单例

public class Singleton {
    private  Singleton(){

    }
    //静态内部类
    //外部类被加载,内部类没有被加载,除非内部类被使用才会被加载
    private static class InSideClass{
        private static Singleton singleton = new Singleton();
    }

    public static Singleton getInstance() {
        return InSideClass.singleton;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值