文章目录
单例模式(Singleton Pattern)
定义:确保一个类只有一个实例,并提供一个全局访问点。
八种方式:
饿汉式(静态变量、静态代码块)
懒汉式(线程不安全、线程安全,同步方法、线程安全、同步代码块)
双重检查
静态内部类
枚举
饿汉式(静态变量):
构造器私有化、类的内部创建对象、向外暴露一个静态的公共方法getInstance、代码实现
优点:类装载的时候就完成了实例化,避免了线程同步的问题
缺点:类装载的时候完成实例化,没有达到Lazy Loading的效果,如果没有用过这个实例,则会造成内存的浪费。
class Singleton{
//
private Singleton(){
}
private final static Singleton instance = new Singleton();
public static Singleton getInstance(){
return instance;
}
}
饿汉式(静态代码块):
优缺点同上。
class Singleton2{
//构造器私有化,外部能创建对象
private Singleton2(){
}
//本类内部创建对象实例
private final static Singleton2 instance;
//创建单例对象
static{
instance = new Singleton2();
}
public static Singleton2 getInstance(){
return instance;
}
}
懒汉式(线程不安全):
优缺点:起到了Lazy Loading的效果,但是只能在单线程下使用
如果在多线程下,一个线程进入了if判断语句块,还没来得及往下执行,另一个也通过了判断语句,会产生多个实例。
不实用。
class Singleton{
private static Singleton instance;
private Singleton(){}
//提供一个静态的公有方法,当使用到该方法时,才去创建instance
public static Singleton getInstance(){
if(instance==null){
instance = new Singleton();
}
return instance;
}
}
懒汉式(线程安全):
优点:解决了线程不安全问题
缺点:效率太低了,每个线程想获得类的实例的时候,都要执行getInstance()方法都要进行同步。而其实这个方法只要执行一次实例化代码就够了,后面想要,直接return,方法进行同步效率太低。
结论:不推荐使用。
class Singleton{
private static Singleton instance;
private Singleton(){}
//提供一个静态的公有方法,当使用到该方法时,才去创建instance
//加入了同步代码,解决线程不安全问题
public static synchronized Singleton getInstance(){
if(instance==null){
instance = new Singleton();
}
return instance;
}
}
懒汉式(线程安全,同步代码块):
优缺点:本意是想对上面的改进,因为效率太低,但是这种同步不能起到线程同步的作用。
双重检查:
class Singleton{
private static volatile Singleton instance;
private Singleton(){}
public static Singleton getInstance(){
if(instance==null){
synchronized(Singleton.class){
if(instance==null){
instance = new Singleton();
}
}
}
return instance;
}
}
静态内部类:
优缺点:
class Singleton{
private static volatile Singleton instance;
private Singleton(){}
//写一个静态内部类,该类中有一个静态属性Singleton
private static class SingletonInstance{
private static final Singleton INSTANCE = new Singleton();
}
public static synchronized Singleton getInstance(){
return SingletonInstance.INSTANCE;
}
}
枚举:
优缺点:
enum Singleton{
INSTANCE;
public void method(){
}
}