你知道单例模式几种写法吗?
我们知道Java中有23种设计模式,单例模式是其中的一种,你知道单例模式有几种写法吗?
1.饿汉式
public class Singleton_1 {
private static final Singleton_1 INSTANCE = new Singleton_1();
private Singleton_1(){
}
public Singleton_1 getInstance(){
return INSTANCE;
}
}
优点:最简单的写法
缺点:无论使用或者不使用都会给它分配出一块内存出来
2.静态代码块方式
public class Singleton_2 {
private static Singleton_2 Instance;
static {
Instance = new Singleton_2();
}
private Singleton_2(){
}
public static Singleton_2 getInstance(){
return Instance;
}
}
优点:简单快捷
缺点:浪费内存
3.懒汉式
public class Singleton_3 {
private static Singleton_3 INSTANCE = null;
private Singleton_3() {
}
public static Singleton_3 getInstance(){
if(INSTANCE==null){
return new Singleton_3();
}
return INSTANCE;
}
}
优点:与饿汉式相比,在不用的情况下不会分配出内存了,只有在用的情况下,getInstance方法才会new出该对象
缺点:线程不安全,当第一个线程走到if时,第二个线程也走到if并且继续往下执行了,这样第一个线程也会继续往下走,会出现多个对象。
4.方法加锁
public class Singleton_4 {
private static Singleton_4 INSTANCE = null;
private Singleton_4() {
}
public static synchronized Singleton_4 getInstance(){
if(INSTANCE==null){
return new Singleton_4();
}
return INSTANCE;
}
}
优点:线程安全
缺点:synchronized锁的范围太大了,因为只需要锁住return new Singleton_3();即可
5.方法内加锁并检查:
public class Singleton_5 {
private static Singleton_5 instance = null;
private Singleton_5() {
}
public static Singleton_5 getInstance() {
if (instance == null) {
synchronized (Singleton_5.class) {
instance = new Singleton_5();
}
}
return instance;
}
}
优点:synchronized锁的范围小了
缺点:线程不完全,当两个线程同时到if是判断对象为null,两个线程同时去if里面抢锁,最终两个线程都会走完里面的代码,new出两个不同的对象。
6.方法内加锁双重检查
public class Singleton_6 {
private volatile static Singleton_6 instance = null;
private Singleton_6(){
}
public static Singleton_6 getInstance(){
if(instance==null){
synchronized (Singleton_5.class){
if(instance==null){
instance = new Singleton_6();
}
}
}
return instance;
}
}
优点:线程安全,不会和上一种出现两个对象。
缺点:无
7.内部类的实现方式
public class Singleton_7 {
private Singleton_7(){
}
private static class InstanceHolder{
static final Singleton_7 INSTANCE = new Singleton_7();
}
public static Singleton_7 getInstance(){
return InstanceHolder.INSTANCE;
}
}
优点:直接从内部类中获取对象,与第一种写法类似
缺点:与第一种写法相比,不会出现浪费内存的现象,内部类默认是不加载的,什么时候用到,什么时候加载。
8.枚举方式
public enum Singleton_8 {
INSTANCE;
public Singleton_8 getInstance(){
return INSTANCE;
}
}
优点:最完美,不仅可以解决线程同步,还可以防止反序列化,枚举类没有构造方法
缺点:无