单例模式的定义
保证一个系统中仅有一个实例,并向外提供一个访问它的全局访问点。这样做的好处是可以节省内存、尤其可以保证数据的一致性,
比如说: window系统中的回收站,整个window系统就一个回收站,这样不管你用什么方法打开回收站,都看到的是同样的内容.保证了数据的一致性.
单例模式的特点
单例模式有 3 个特点:
- 单例类只有一个实例对象
- 该单例对象必须由单例类自行创建
- 单例类对外提供一个访问该单例的全局访问点
单例模式的实现
根据创建对象的时机,分为如下两种:
恶汉式(饥汗式)
特点:
- 不存在线程安全问题
/**
* 步骤:
* 1, 私有构造 -> 那么外部无法创建对象了
* 2, 在成员位置创建当前对象
* 3, 对外提供一个访问对象的方法
*/
public class Singleton {
//1
private Singleton() {
}
//2
private static Singleton singleton = new Singleton();
//3
public static Singleton getinstance(){
return singleton;
}
}
懒汉式
特点
- 什么时候使用,什么时候创建
- 存在线程安全问题
/**
* 步骤:
* 1, 私有构造 -> 那么外部无法创建对象了
* 2, 在成员位置声明对象
* 3, 对外提供一个访问对象的方法,并创建对象
*/
public class Singleton {
//1
private Singleton() {
}
//2
private static Singleton singleton = null;
//3
public static Singleton getinstance(){
if (singleton == null){
singleton = new Singleton();
}
return singleton;
}
}
懒汉式2(解决线程安全问题)
特点
- 有同步的情况,会降低性能
/**
* 步骤:
* 1, 私有构造 -> 那么外部无法创建对象了
* 2, 在成员位置声明对象 -> 并加上volatile 保证所有线程可见
* 3, 对外提供一个访问对象的方法,并创建对象 -> 创建是同步的方法(synchronized)
*/
public class Singleton {
//1
private Singleton() {
}
//2
private static volatile Singleton singleton = null;
//3
public static synchronized Singleton getinstance(){
if (singleton == null){
singleton = new Singleton();
}
return singleton;
}
}
外部测试
public static void main(String[] args) {
Singleton getinstance = Singleton.getinstance();
Singleton getinstance1 = Singleton.getinstance();
System.out.println(getinstance); //内存地址: Singleton@dc24521
System.out.println(getinstance1);//内存地址: Singleton@dc24521
}
相同的内存地址,所有可以证明是同一个对象.