1.什么是单例模式:
在有些系统中,为了节省内存资源、保证数据内容的一致性,对某些类要求只能创建一个实例,这就是所谓的单例模式。
2.单例模式的定义与特点:
定义:指一个类只有一个实例,且该类能自行创建这个实例的一种模式。
特点:
- 单例类只有一个实例对象;
- 该单例对象必须由单例类自行创建;
- 单例类对外提供一个访问该单例的全局访问点;
单例模式是设计模式中最简单的模式之一。通常,普通类的构造函数是公有的,外部类可以通过“new 构造函数()”来生成多个实例。但是,如果将类的构造函数设为私有的,外部类就无法调用该构造函数,也就无法生成多个实例。这时该类自身必须定义一个静态私有实例,并向外提供一个静态的公有函数用于创建或获取该静态私有实例。
Singleton 模式通常有两种实现形式:
饿汉式:
package singleton;
/**
* 饿汉式单例
* 特点:类一旦加载就创建一个单例,保证在调用getInstance方法之前单例已经存在了
*/
public class HungrySingleton {
private static final HungrySingleton instance = new HungrySingleton();
//私有构造,避免外部初始化
private HungrySingleton() {
}
//静态公有方法,获取该实例对象
public static HungrySingleton getInstance() {
return instance;
}
}
懒汉式第一种:
package singleton;
/**
* 懒汉式单例
* 特点:只有在调用getInstance方法时才会创建实例对象
*/
public class LazySingleton {
private static LazySingleton instance = null;
private LazySingleton() {
}
/**
* 问题:
* 使用synchronized关键字修饰,可以保证线程安全性;
* 但同时有synchronized关键字修饰,所以该多线程访问时,都要判断锁,会导致效率较低
*/
public static synchronized LazySingleton getInstance() {
if (instance == null) {
instance = new LazySingleton();
}
return instance;
}
}
懒汉式第二种:
package singleton;
/**
* 懒汉式更好的解决方案:使用双判断的方式
*/
public class Lazy {
public static Lazy instance = null;
private Lazy() {
}
/**
* 使用双重判断的方式来解决懒汉式的效率问题,即当一个线程创建了该实例对象,以后的线程访问的时候该对象 * 就不为null,既不用再去判断锁了,这样可以减少判断锁的次数,提高了效率
*/
public static Lazy getInstance() {
if (instance == null) {
//静态方法的锁使用的是改静态方法所在类的class文件对象
synchronized (Lazy.class) {
if (instance == null) {
instance = new Lazy();
}
}
}
return instance;
}
}
1.懒汉式和饿汉式的区别:
懒汉式的特点在于实例的延迟(所以是懒汉式)加载;
2.懒汉式有什么问题:
如果多线程访问时会出现安全问题,可以加同步(synchronized)来解决,但是效率较低
3.怎么解决懒汉式效率低的问题:
可以使用双重判断可以解决这个问题
4.加同步的时候,使用的锁是哪一个:
该类所属的字节码文件对象(静态)