一 单列模式
1.概念
单例模式(Singleton Pattern)。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。
注意:
1.单例类只能有一个实例。
2.单例类必须自己创建自己的唯一实例。
3.单例类必须给所有其他对象提供这一实例。
2.单列模式的几种写法
/**
* @Author yqq
* @Date 2021/4/17 22:34
* @Version 1.0
*/
/**
* 1.饿汉式(静态常量)
*/
public class Singleton {
/**
* ・优点:这种写法比较简单,就是在类装载的时候就完成实例化。避免了线程同步问题。
* ・缺点:在类装载的时候就完成实例化,没有达到Lazy Loading的效果。如果从始至终从未使用过这个实例,则会造成内存的浪费。
*/
private final static Singleton INSTANCE=new Singleton();
public Singleton() {
}
public static Singleton getInstance(){
return INSTANCE;
}
}
/**
* 2.饿汉式(静态代码块)
*/
class Singleton1{
/**
* 这种方式和上面的方式其实类似,只不过将类实例化的过程放在了静态代码块中,也是在类装载的时候,就执行静态代码块中的代码,
* 初始化类的实例。优缺点和上面是一样的。
*/
private static Singleton1 INSTANCE;
static {
INSTANCE=new Singleton1();
}
private Singleton1(){
}
public Singleton1 getInstance(){
return INSTANCE;
}
}
/**
* 3.懒汉式(线程不安全)
*/
class Singleton2{
/**
* 这种写法起到了 Lazy Loading的效果,但是只能在单线程下使用。如果在多线程下,
* 一个线程进入了 if (singleton == null)判断语句块,还未来得及往下执行,另一个线程也通过了这个判断语句,这时便会产生多个实例。
* 所以在多线程环境下不可使用这种方式。
*/
private static Singleton2 INSTANCE;
private Singleton2(){
}
public static Singleton2 getInstance(){
if(INSTANCE==null){
INSTANCE=new Singleton2();
}
return INSTANCE;
}
}
/**
* 4.懒汉式(线程安全,同步方法)
*/
class Singleton3{
/**
* 解决上面第三种实现方式的线程不安全问题,做个线程同步就可以了,于是就对 getInstance()方法进行了线程同步。
* •缺点:效率太低了,每个线程在想获得类的实例时候,执行getInstance() 方法都要进行同步。
* 而其实这个方法只执行一次实例化代码就够了,后面的想获得该类实例,直接return就行了。方法进行同步效率太低要改进。
*/
private static Singleton3 INSTANCE;
private Singleton3(){
}
public static synchronized Singleton3 getInstance(){
if(INSTANCE==null){
INSTANCE=new Singleton3();
}
return INSTANCE;
}
}
/**
* 5.懒汉式(线程安全,同步代码块)
*/
class Singleton4{
/**
* 由于第四种实现方式同步效率太低,所以摒弃同步方法,改为同步产生实例化的的代码块。
* 但是这种同步并不能起到线程同步的作用。跟第3种实现方式遇到的情形一致,假如一个线程进入了 if (singleton == null)判断语句块,
* 还未来得及往下执行,另一个线程也通过了这个判断语句,这时便会产生多个实例。
*/
private static Singleton4 INSTANCE;
private Singleton4(){
}
public static Singleton4 getInstance(){
if(INSTANCE==null){
synchronized (Singleton4.class){
INSTANCE=new Singleton4();
}
}
return INSTANCE;
}
}
/**
* 6.双重検查
*/
class Singleton5{
/**
* Double-Check概念对于多线程开发者来说不会陌生,如代码中所示,
* 我们进行了两次if (singleton == null)检查,这样就可以保证线程安全了。
* 这样,实例化代码只用执行一次,后面再次访问时,判断if (singleton == null),直 接return实例化对象。
* •优点:线程安全;延迟加载;效率较高。
*/
private static Singleton5 INSTANCE;
private Singleton5(){
}
public static Singleton5 getInstance(){
if(INSTANCE==null){
synchronized (Singleton5.class){
if(INSTANCE==null){
INSTANCE=new Singleton5();
}
}
}
return INSTANCE;
}
}