1.饿汉式,这种方式不推荐,会造成资源的浪费。
public class Hungry {
private Hungry(){
}
private static Hungry hungry = new Hungry();
public static Hungry getInstance(){
return hungry;
}
public static void main(String[] args) {
Hungry hungry1 = Hungry.getInstance();
Hungry hungry2 = Hungry.getInstance();
System.out.println(hungry1);
System.out.println(hungry2);
}
}
2.单线程中的懒汉式
public class LazyMan {
private LazyMan(){
}
private static LazyMan lazyMan = null;
public static LazyMan getInstance(){
if(lazyMan == null){
lazyMan = new LazyMan();
}
return lazyMan;
}
public static void main(String[] args) {
LazyMan lazyMan1 = LazyMan.getInstance();
LazyMan lazyMan2 = LazyMan.getInstance();
System.out.println(lazyMan1);
System.out.println(lazyMan2);
}
}
3.双重锁机制的懒汉式,最推荐的一种
public class ThreadLazyMan {
private ThreadLazyMan(){
System.out.println(Thread.currentThread().getName());
}
private static volatile ThreadLazyMan lazyMan = null;
public static ThreadLazyMan getInstance(){
if(lazyMan == null){
synchronized (ThreadLazyMan.class){
if(lazyMan == null){
lazyMan = new ThreadLazyMan();
}
}
}
return lazyMan;
}
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
new Thread(()->{
ThreadLazyMan.getInstance();
}).start();
}
}
}
4.静态内部类的饿汉式
public class LazyInnerClass {
private LazyInnerClass(){
System.out.println(Thread.currentThread().getName());
}
static class Inner{
public static LazyInnerClass lazyInnerClass = new LazyInnerClass();
}
public static LazyInnerClass getInstance(){
return Inner.lazyInnerClass;
}
public static void main(String[] args) {
for (int i = 0; i < 100; i++) {
new Thread(()->{
LazyInnerClass.getInstance();
}).start();
}
}
}
5.枚举,最为安全的模式,反射也无法破解
public enum SingleEnum {
INSTANCE;
public static SingleEnum getInstance(){
return INSTANCE;
}
}
总结:
前面4种方式,不管如何优化,在反射面前都是不安全的。
枚举是安全的,枚举的源码中,进行反射会直接抛异常。
原文:https://www.cnblogs.com/johnzhao/p/14672024.html