单例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:建议使用枚举,好用又简单啊…