目录
1.什么是单例模式
2.单例模式的类型
3.饿汉模式
4.饿汉模式
5.多线程
单例模式是指内存中只会创建且仅创建一次对象的设计模式.单例模式可以让程序仅在内存中创建一个对象,让所有需要调用的地方都共享这一单例对象.
饿汉模式:类内部把实例创建好,等待被程序使用,禁止外部重新创建实例
懒汉模式:在真正需要使用对象时去创建对象
编码时就指明要马上创建对象,不要等到被调用时去创建
实现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}
外部无论怎么调用都是一个对象,不能创建新的对象
懒汉式创建对象的方法是在程序使用对象前,先判断该对象是否已经实例化(判空),若已实例化直接返回该类对象,否则则先执行实例化操作。
实现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(){}
}
因为饿汉模式只有读,所以没有线程安全问题
但是懒汉模式有读有写,所以存在线程安全问题
就该问题解决办法
1.加锁,把if和new变成原子操作
2.双重if,减少不必要的加锁
3.使用volatile指令从排序,保证后序线程能拿到完整的对象
class SingletonLazy{volatile private static SingletonLazy instance=null;public static SingletonLazy getInstance(){if(instance==null){//两个或多个线程同时看到后,满足继续,不满足返回instancesynchronized(SingletonLazy.class){if(instance==null){//一个线程进入,另一个线程就不会进入instance=new SingletonLazy();}}}return instance;}