目录
1.什么是单例模式
单例模式是指内存中只会创建且仅创建一次对象的设计模式.单例模式可以让程序仅在内存中创建一个对象,让所有需要调用的地方都共享这一单例对象.
2.单例模式的类型
饿汉模式:类内部把实例创建好,等待被程序使用,禁止外部重新创建实例
懒汉模式:在真正需要使用对象时去创建对象
3.饿汉模式
编码时就指明要马上创建对象,不要等到被调用时去创建
实现Singleton类步骤:
1.定义唯一实例本体
private是私有的,static是类的属性
JVM中,每个类对象只有一份
2.获取实例方法
因为不能在外部创建实例,所以要编写方法,用来调用唯一实例对象
3.禁止外部new实例
把构造方法的修饰符写为private
class Singleton{
//唯一实例本体
private static Singleton instance=new Singleton();
//获取实例的方法
public static Singleton getInstance(){
return instance;
}
//禁止外部new实例
private Singleton(){
}
}
测试
public static void main(String[] args) {
//s1,s2是同一个对象
Singleton s1=Singleton.getInstance();
Singleton s2=Singleton.getInstance();
//Singleton s3=new Singleton();error
}
外部无论怎么调用都是一个对象,不能创建新的对象
4.饿汉模式
懒汉式创建对象的方法是在程序使用对象前,先判断该对象是否已经实例化(判空),若已实例化直接返回该类对象,否则则先执行实例化操作。
实现SingletonLazy类步骤:
1.定义实例
private是私有的,static是类的属性
JVM中,每个类对象只有一份
因为非必要不创建,所以实例对象为空
2.获取实例的方法
先判断该对象是否已经实例化(判空),若已实例化直接返回该类对象,否则则先执行实例化操作。
3.禁止外部new实例
把构造方法的修饰符写为private
class SingletonLazy{
private static SingletonLazy instance=null;
public static SingletonLazy getInstance(){
if(instance==null){
instance=new SingletonLazy();
}
return instance;
}
private SingletonLazy(){
}
}
5.多线程
因为饿汉模式只有读,所以没有线程安全问题
但是懒汉模式有读有写,所以存在线程安全问题
就该问题解决办法
1.加锁,把if和new变成原子操作
2.双重if,减少不必要的加锁
3.使用volatile指令从排序,保证后序线程能拿到完整的对象
class SingletonLazy{
volatile private static SingletonLazy instance=null;
public static SingletonLazy getInstance(){
if(instance==null){//两个或多个线程同时看到后,满足继续,不满足返回instance
synchronized(SingletonLazy.class){
if(instance==null){//一个线程进入,另一个线程就不会进入
instance=new SingletonLazy();
}
}
}
return instance;
}