写一个单例模式?

单例1:

/**
 * 单例模式-饿汉式线程安全
 * @author 魏
 * @Date 2020/3/16 0016
 **/
public class Singleton {
    /**饿汉式**/
    private static final Singleton singleton=new Singleton();

    /**私有化构造器**/
    private Singleton() {

    }
    /**提供公共静态方法 获取单例对象**/
    public  static Singleton getSingleton(){
        return Singleton.singleton;
    }

    public static void main(String[] args) {
     	 Singleton A= Singleton.getSingleton();
        Singleton B= Singleton.getSingleton();
        System.out.println("比较是否地址相同:"+ (A==B));
    }

}

单例2:

/**
 * 懒汉式单例,线程不安全
 *
 * @author 魏
 * @Date 2020/3/16 0016
 **/
public class Singleton2 {
    /**没有实例化的对象,不用final修饰**/
    private static Singleton2 singleton2;

    /**私有化构造器**/
    private Singleton2() {
    }


    /**获取单例,没有同步方法线程不安全**/
    public static Singleton2 getInstance() {
        //判断对象是否实例化?
        if (singleton2 == null) {
            Singleton2.singleton2 = new Singleton2();
        }
        return singleton2;
    }

    public static void main(String[] args) {
        Singleton2 a=Singleton2.getInstance();
        Singleton2 b=Singleton2.getInstance();
        System.out.println(a==b);
    }

}

单例3:

/**
 * 懒汉式单例-线程安全的方式
 *
 * @author 魏
 * @Date 2020/3/16 0016
 **/
public class Singleton2 {
    /**没有实例化的对象**/
    private static Singleton2 singleton2;

    /**私有化构造器**/
    private Singleton2() {
    }


    /**获取单例,synchronized同步方法,线程安全**/
    public static synchronized Singleton2 getInstance() {
        //判断对象是否实例化?
        if (singleton2 == null) {
            Singleton2.singleton2 = new Singleton2();
        }
        return singleton2;
    }

    public static void main(String[] args) {
        Singleton2 a=Singleton2.getInstance();
        Singleton2 b=Singleton2.getInstance();
        System.out.println(a==b);
    }

}

单例4:

/**
 * 双检锁单例模式
 * 线程安全
 *
 * @author 魏
 * @Date 2020/3/16 0016
 **/
public class Singleton3 {
    //轻量级锁
    private volatile static Singleton3 singleton3;

    //私有构造器
    private Singleton3() {
    }

    //双检锁
    public static Singleton3 getInstance() {
        //不为空 直接返回实例,为空进入逻辑
        if (null == singleton3) {
            //同步锁 锁住对象  假如同时几个线程进入还没有实例
            //那么锁住可以保证只创建一个实例对象 保证单例
            synchronized (Singleton3.class) {
                //为空才创建对象,因为多线程可能同时进入,那么第一个锁住类对象 实例化它
                //然后释放锁 其他线程检查类实例化了没? 不为空返回对象
                if (null == singleton3) {
                    singleton3 = new Singleton3();
                }


            }
        }
        return singleton3;
    }

    public static void main(String[] args) {
        Singleton3 a = Singleton3.getInstance();
        Singleton3 b = Singleton3.getInstance();
        System.out.println(a == b);
    }

}

单例5:枚举

/**
 * 枚举颜色
 * @author 魏
 * @Date 2020/3/17 0017
 **/
public enum Color {
//jdk1.5后枚举可以列举单例  而且更丰富
//Color颜色
    YELLOW,BLANK,RED
}

/**
 * @author 魏
 * @Date 2020/3/17 0017
 **/
public class Test {
    public static void main(String[] args) {
        Color color = Color.RED;
        System.out.println(color);

    }
}


枚举充电:

/**
 * 枚举
 * @author 魏
 * @Date 2020/3/17 0017
 **/

public enum Singleton5 {
//有参单例,名字叫ERROR
    ERROR(0,"状态消息:失败"),
    //有参单例,名字叫OK
    OK(1,"状态消息:成功");
    //成员属性
    private  Integer status;
    private  String  msg;

    /**
    * 有参构造私有
     * @param status 状态码
     * @param msg  消息
     */
    private  Singleton5(Integer status,String msg){
        this.status=status;
        this.msg=msg;
    }
//get set toString
    public Integer getStatus() {
        return status;
    }

    public void setStatus(Integer status) {
        this.status = status;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

    @Override
    public String toString() {
        return "Singleton5{" +
                "status=" + status +
                ", msg='" + msg + '\'' +
                '}';
    }
}

----------------------------------------------
	  Singleton5 singleton5=Singleton5.OK;
        System.out.println("枚举:"+singleton5.toString());
     --------------------------------------
        枚举:Singleton5{status=1, msg='状态消息:成功'}

可以看到 我们只要有私有构造方法(有参或者无参,不写默认提供无参),就可以直接通过 实例名称来创建单例,前后端分离状态码可以使用这个来写.

这个和我们的传统单例模式都差不多,传统的一般是私有化构造器,公共方法获取一个实例化对象,你需要保证的是对象只有一个.

而枚举是直接通过实例名字表示单例对象.
比如:

public enum Color {
    YELLOW,BLANK,RED
    //省略了无参构造
}

如果需要有参 就需要定义有参构造函数

public enum Color {
    //实例对象,每一个都是单例
    YELLOW("黄色"),BLANK("黑色"),RED("红色");
    //构造器
    private Color(String msg){
    this.msg=msg;
    }
 private String msg;
 //省略get set等方法
}

ps:建议使用枚举,好用又简单啊…

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章