目的:
单例模式顾名思义其实就是利用某种方法保证某个类只有一个对象存在。
分类:
单例模式分为: 饿汉式(静态常量,静态代码块),懒汉式(线程不安全,线程安全同步方法,线程安全同步代码块),双重检查,静态内部类,枚举
饿汉式
为什么叫饿汉式?原因在使用之前提前就将对象实例化好了。正因如此,饿汉式就保证了线程安全。
静态常量
public class Singleton
{
private Singleton{};
private final static Singleton instance = new Singleton();
public static Singleton getInstance()
{
return instance;
}
}
静态代码块
public class Singleton
{
private Singleton{};
private final static Singleton instance;
static
{
instance = new Singleton();
}
public static Singleton getInstance()
{
return instance;
}
}
懒汉式:相比较与饿汉式可以实现延迟加载
线程不安全式:不安全体现在判断instance == null空处,如果有多个线程同时满足条件则导致线程不安全!
public class Singleton
{
private Singleton{};
private static Singleton instance = null;
public static Singleton getInstance()
{
if(instance == null)
{
instance = new Singleton();
}
return instance;
}
}
线程安全式:同步方法
保证了安全,但同步方法降低了效率
当前synchronized的锁是Singleton.class对应的Class对象
public class Singleton
{
private Singleton{};
private static Singleton instance = null;
public static synchronized Singleton getInstance()
{
if(instance == null)
{
instance = new Singleton();
}
return instance;
}
}
线程安全式:同步代码块(实际上是不安全的,如果有多个线程同时通过if语句将创建多个对象)
public class Singleton
{
private Singleton{};
private static Singleton instance = null;
public static Singleton getInstance()
{
if(instance == null)
{
synchronized(Singleton.class){
instance = new Singleton();
}
}
return instance;
}
}
双重检查
class Singleton {
private static volatile Singleton instance;
private Singleton() {}
//提供一个静态的公有方法,加入双重检查代码,解决线程安全问题, 同时解决懒加载问题
//同时保证了效率, 推荐使用
public static synchronized 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();
}
//提供一个静态的公有方法,直接返回SingletonInstance.INSTANCE
public static synchronized Singleton getInstance() {
return SingletonInstance.INSTANCE;
}
}
枚举式:
利用了枚举类本身单例的性质。
//使用枚举,可以实现单例, 推荐
enum Singleton {
INSTANCE; //属性
public void sayOK() {
System.out.println("ok~");
}
}