什么是单例模式
单例(单个的实例)
1.所谓单例设计模式,就是采取一定的方法保证在整个的软件系统中,对某个类只能存在一个对象实例,并且该类只提供一个取得其对象实例的方法
2.单例设计模式有两种方式:饿汉式 与 懒汉式
饿汉式:
饿汉式听名字就知道它就像一个饿死鬼一样,有饭就赶紧吃,有饭就抢着吃。
所以,在程序启动或单例模式类被加载的时候,单例模式实例就已经被创建。
创建步骤:
1)构造器私有化 —>防止直接new对象
2)类的内部创建对象
3)向外暴露一个静态的公共方法 (getInstance)
//饿汉式
public class SingletonTest {
//私有化类的构造器,让外部无法调用
private SingletonTest(){
}
//类的内部创建类的对象,并且此对象必须声明静态
private static SingletonTest instance= new SingletonTest();
//提供公共的静态的方法,返回类的对象
public static SingletonTest getInstance(){
return instance;
}
}
懒汉式:
懒汉式顾名思义就像一个懒惰的大汉,能不干活就不干活。所以它直到第一次去使用的时候,才会创建实例对象。
实现步骤:
1.仍然构造器私有化
2.定义一个 static 静态属性对象
3.提供一个 public 的 static 方法,可以返回一个对象
4.懒汉式,只有当用户使用 getInstance 时,才返回对象, 后面再次调用时,会返回上次创建的对象
线程不安全模式
class Singleton{
//私有化类的构造器
private Singleton(){
}
//声明当前类的对象,并且是static,但是没有赋值
private static Singleton instance = null;
//声明为public、static的方法用来返回类的实例
//如果发现当且instance为null,给instance创建一个实例。
public static Singleton getInstance(){
if(instance == null){
instance = new Singleton();
}
return instance;
}
}
线程安全模式:
class Singleton{
//私有化类的构造器
private Singleton(){
}
//声明当前类的对象,并且是static,但是没有赋值
//此处添加volatile是为了防止指令重排序
private static volatile Singleton instance = null;
//声明为public、static的方法用来返回类的实例
//如果发现当且instance为null,给instance创建一个实例。
public static Singleton getInstance(){
if(instance == null){
synchronized(Singleton.class){
if(instance == null){
//这并不是一个原子操作
//1.给instance分配内存空间
//2.调用Singleton构造函数初始化
//3.将instance对象指向分配的内存空间,此时instance不为null
//使用volatile修饰instance就是防止这1-2-3步被指令重排,保证其顺序执行
instance = new Singleton();
}
}
}
return instance;
}
}
简简单单的总结一下吧
1.二者最主要的区别在于创建对象时机不同:
1)饿汉式是在类加载就创建了对象
2)懒汉式是在使用时在会创建对象
2.饿汉式不存在线程安全问题,懒汉式存在线程安全问题
3.饿汉式存在浪费资源的可能,因为它是在类加载的时候就创建了对象吗, 如果我们不使用它,那不就浪费了。
懒汉式是在使用的时候才会创建,所以就不存在这个问题啦。
补充:在我们javaSE标准类中,java.lang.Runtime
就是经典的单例模式。