单例模式 四种

  1. 饿汉式

单例模式 饿汉式类加载到内存后,实例化一个单例,jvm保证线程安全(都不能创建新的,所以安全,多线程都是安全的)
简单易用
缺点:不管是否用到,类加载时候就会实例化,浪费
一般项目开发中加载是用的Class.forName("") //将class加载到内存,但不实例化,此时,如果使用饿汉,就会消耗内存,所以产生了懒汉式

package DesignPatter.sington;

/**
 * @author Susuper
 * @version 1.0
 * @date 2020/1/12 20:52
 * @description
 * 单例模式 饿汉式类加载到内存后,实例化一个单例,jvm保证线程安全(都不能创建新的,所以安全,多线程都是安全的)
 * 简单易用
 * 缺点:不管是否用到,类加载时候就会实例化,浪费
 * 一般项目开发中加载是用的Class.forName("") //将class加载到内存,但不实例化,此时,如果使用饿汉,就会消耗内存,所以产生了懒汉式
 */
public class Mag01 {
    private static  final  Mag01 INSTANCE = new Mag01();
    private Mag01(){};  //构造方法私有化
    private void show(){
        System.out.println("饿汉式单例模式构建成功");
    }
    public static Mag01 getInstance(){   //必须设置为static,否则其它无法调用此方法
        return INSTANCE;
    }

    public static void main(String[] args) {
        Mag01 m = Mag01.getInstance();
        Mag01 m2 = Mag01.getInstance();
        System.out.println(m==m2);
    }
}

  1. 饿汉式

lazy loading 懒汉式加载 需要的时候在加载,但是存在线程安全问题

package DesignPatter.sington;

/**
 * @author Susuper
 * @version 1.0
 * @date 2020/1/12 21:02
 * @description
 * lazy loading 懒汉式加载
 * 需要的时候在加载,但是存在线程安全问题
 */
public class Mag02 {
    private  static  Mag02  INSTANCE = null;
    private Mag02(){}
    //加锁 由于这里是static对象 所以锁定的是Mag02 .class
    public static  synchronized  Mag02 getInstance(){
        if (INSTANCE==null){
            //为了体现线程不安全的情况
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
             INSTANCE =  new Mag02();
        }
        return INSTANCE;
    }

    public static void main(String[] args) {
        //匿名内部类开启100个线程
//        for(int i = 0;i<100;i++){
//            new Thread(new Runnable() {
//                @Override
//                public void run() {
//
//                }
//            }).start();
//        }

        //lamda表达式对只有一个方法的匿名内部类的一个简化
        for (int i =0;i<100;i++){
            new Thread(()->{
                System.out.println(Mag02.getInstance().hashCode());
            }).start();
            //当只有一句话的时候还可以简写
//            new Thread(()->
//                    System.out.println(Mag02.getInstance().hashCode())
//            ).start();
        }
    }
}

/**
 new Runnable() {
@Override
public void run() {

}*/
/*
 ()->{

             }*/
  1. 匿名内部类单例模式

完美方式之一
静态内部类方式
jvm负责保证线程安全

不理解的地方,在加载时候,Mag03Handle 是否会被直接加载进入,不理解,主要是无法测试class.forname理解还是不够

public class Mag03 {
    //加载到内存后  并没有去实例化 静态变量
    private static class Mag03Handle{
        private static final Mag03 INSTANCE = new Mag03();
    }
    public static Mag03 getInstance(){
        return Mag03Handle.INSTANCE;
    }


}

  1. 枚举单例

由于枚举不存在构造方法,所以是单例的
不仅可以解决线程同步,还可以防止反序列化

public enum Mag04 {
    INSTANCE;

    public static void main(String[] args) {
        for(int i = 0;i<100;i++){
            new Thread(()->{
                System.out.println(Mag04.INSTANCE.hashCode());
            }).start();
        }
    }
}
···
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值