一:某个类只能有一个实例,构造器私有化
二:他必须自行创建这个实例,含有一个该类的静态变量来保存这个实例
三:它必须自行向整个系统提供这个实例 方式1直接暴露 方式2用静态变量的get方法
饿汉式获取:
1直接实例化(简洁直观)
public class Singleton1 {
public static final Singleton1 INSTANCE = new Singleton1();
private Singleton1(){
}
}
2枚举式(最简洁)
public enum Singleton2 {
INSTANCE
}
3静态代码块(适合复杂实例化),从配置文件中获取构造器参数
public class Singleton3 {
public static final Singleton3 INSTANCE;
@Override
public String toString() {
return "Singleton3{" +
"info='" + info + '\'' +
'}';
}
private String info;
public String getInfo() {
return info;
}
public void setInfo(String info) {
this.info = info;
}
static {
try {
Properties ps=new Properties();
ps.load(Singleton3.class.getClassLoader().getResourceAsStream("Singleton.properties"));
INSTANCE = new Singleton3(ps.getProperty("info"));
} catch (IOException e) {
throw new RuntimeException(e);
}
}
private Singleton3(String info){
this.info=info;
}
}
懒汉式获取:
4线程不安全(适用于单线程) 原因:当线程阻塞未及时创建实例时同时再获取可能会创建新实例
public class Singleton4 {
private static Singleton4 instance;
private Singleton4(){
}
public static Singleton4 getInstance() throws InterruptedException {
if(instance==null){
Thread.sleep(200);
instance=new Singleton4();
}
return instance;
}
}
5线程安全(适用于多线程),加锁
public class Singleton5 {
private static Singleton5 instance;
private Singleton5(){
}
public static Singleton5 getInstance() throws InterruptedException {
if(instance==null){
synchronized (Singleton5.class){
if(instance==null){
Thread.sleep(200);
instance=new Singleton5();
}
}
}
return instance;
}
}
6静态内部类形式(适用于多线程)
public class Singleton6 {
private Singleton6(){
}
public static Singleton6 getInstance() throws InterruptedException {
return inner.INSTANCE;
}
private static class inner{
private static final Singleton6 INSTANCE = new Singleton6();
}
}