单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。
注意:
1、单例类只能有一个实例。
2、单例类必须自己创建自己的唯一实例。
3、单例类必须给所有其他对象提供这一实例。
介绍
意图:保证一个类仅有一个实例,并提供一个访问它的全局访问点。
主要解决:一个全局使用的类频繁地创建与销毁。
何时使用:当您想控制实例数目,节省系统资源的时候。
如何解决:判断系统是否已经有这个单例,如果有则返回,如果没有则创建。
关键代码:单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。
注意:
1、单例类只能有一个实例。
2、单例类必须自己创建自己的唯一实例。
3、单例类必须给所有其他对象提供这一实例。
介绍
意图:保证一个类仅有一个实例,并提供一个访问它的全局访问点。
主要解决:一个全局使用的类频繁地创建与销毁。
何时使用:当您想控制实例数目,节省系统资源的时候。
如何解决:判断系统是否已经有这个单例,如果有则返回,如果没有则创建。
关键代码:构造函数是私有的。
public class Hungry {
// 饿汉式问题:浪费内存。这是饿汉式,内存立刻加载这4个资源。所以立刻初始化四个字节数组,非常占用内存资源。
private Byte[] data1 = new Byte[1024*1024];
private Byte[] data2 = new Byte[1024*1024];
private Byte[] data3 = new Byte[1024*1024];
private Byte[] data4 = new Byte[1024*1024];
private Hungry(){
//1、单例中最重要的思路,构造器私有。保证内存中只有一个对象
}
//2.生成饿汉式对象,这里直接new对象
private final static Hungry hungry = new Hungry();
//3.getInstance()方法
public static Hungry getInstance(){
return hungry;
}
}
public class Lazy {
//懒汉式先私有化构造方法
private Lazy(){
}
//这里先不new对象
private static Lazy lazy;
//实现getInstance方法,注意返回值
public static Lazy getInstance(){
if(lazy==null){ //这里检测为null才创建,所以叫懒汉式
lazy = new Lazy();
}
return lazy;
}
}
/**
但是单线程下简单些没问题,但是多线程并发下,不可以。
**/
改进,加双重检测锁机制。
public class Lazy {
private Lazy(){
}
private static Lazy lazy;
public static Lazy getInstance(){
// 加锁
// 双重检测锁模式的懒汉式单例
if(lazy==null){ //这里检测为null才创建,所以叫懒汉式
synchronized (Lazy.class){ //锁class只有一个
if (lazy==null){
lazy = new Lazy();
}
}
}
return lazy;
}
}
//但是,这个存在问题,就是 lazy = new Lazy(); 该代码可能会发生指令重排
//改进为添加volatile
添加volatile
public class Lazy {
private Lazy(){
}
//此添加volatile 关键字
private volatile static Lazy lazy;
public static Lazy getInstance(){
// 加锁
// 双重检测锁模式的懒汉式单例
if(lazy==null){ //这里检测为null才创建,所以叫懒汉式
synchronized (Lazy.class){ //锁class只有一个
if (lazy==null){
lazy = new Lazy();
//不是原子性操作,底层分为三步,有可能发生指令重排
//1.分配内存空间
//2.执行构造方法初始化对象
//3.对象指向空间才能保证对象NEW完了
//改进:第7行加violate lazy满没有完成构造,空间是虚无的
}
}
}
return lazy;
}
改进:红绿灯法、静态内部类、枚举类型