单例模式是一种比较常用的设计模式,常用的有下面的一下五种。创建的时候多线程是否安全这一点需要特别注意的。
package org.openjdk.jcstress.tests.executors;
import java.util.UUID;
public class DemoSingle {
public static void main(String[] args) {
DemoSingle4.INSTANC.getUuid();
DemoSingle4.INSTANC.getUuid();
}
}
/* 懒汉模式 */
class DemoSingle1 {
private static DemoSingle1 instanc;
//默认是构造函数是public这里必须显示的改成private
private DemoSingle1(){}
/*此处需要注意 是static 方法,必须添加synchronize关键字否则为不安全的单例方式*/
public static synchronized DemoSingle1 getInDemoSingle(){
if(instanc==null){
instanc=new DemoSingle1();
}
return instanc;
}
}
/*饿汉模式 为线程安全的单例模式*/
class DemoSingle2 {
private static DemoSingle2 instanc=new DemoSingle2();
//默认是构造函数是public这里必须显示的改成private
private DemoSingle2(){}
/**/
public static DemoSingle2 getInDemoSingle(){
return instanc;
}
}
/*静态类单例模式,好处是内部类外部无法访问*/
/*静态内部类比较常用*/
class DemoSingle3 {
private static class MyInstanc{
private static DemoSingle3 instanc=new DemoSingle3();
}
private DemoSingle3(){}
public static DemoSingle3 getinstanc(){
return MyInstanc.instanc;
}
}
/*枚举模式*/
enum DemoSingle4{
INSTANC;
private String uuid;
private DemoSingle4(){
uuid=UUID.randomUUID().toString();
}
public void getUuid(){
System.out.println(uuid);
}
}
/*双检索*/
class DemoSingle5{
/*volatile只保证可见性和顺序性,并没有保证原子性,所以它能保证instac被修改后其他线程立马可见但不能保证安全性*/
private static volatile DemoSingle5 instac;
private DemoSingle5(){}
public static DemoSingle5 getInstanc(){
if(instac==null){
synchronized (DemoSingle5.class) {
/*此处需要在此判断instac是否被创建成功*/
if(instac==null)
instac=new DemoSingle5();
}
}
return instac;
}
}