单例模式
含义:
单例模式是一种设计模式,对于特定的类,它仅仅允许实例化一次对象(此时使用的内存区域已经定下来了,以后都是使用的这一内存区域的对象,直至运行结束),不允许直接通过“new+类名()“ 获取多个不同的对象。
实现:
- 饿汉式------线程安全的,推荐使用
(1)构造函数通过私有化阻止多次创建多个不同的对象;
(2)一个类中的私有属性或方法只能在本类访问或使用;
(3)外界只能访问public属性或方法;
(4)没法实例化,只能通过”类名.方法名“这种静态(static)才能获取实例化对象,所以获取实例的方法必须声明为public static,相应的私有的实例化对象只能是由static修饰。
这里我们就实现了单例效果,测试结果如下:
这验证了我们的结论。
- 懒汉式------线程不安全的,不推荐使用
实现方法可以参考下面的类:
这里我们就实现了单例效果,测试结果如下:
相同的地址,验证了我们的结论。
什么叫线程安全
如果你的代码所在的进程中有多个线程在同时运行,而这些线程可能会同时运行这段代码。如果每次运行结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的是一样的,就是线程安全的。
或者说:一个类或者程序所提供的接口对于线程来说是原子操作或者多个线程之间的切换不会导致该接口的执行结果存在二义性,也就是说我们不用考虑同步的问题。
线程安全问题都是由全局变量及静态变量引起的。
若每个线程中对全局变量、静态变量只有读操作,而无写操作,一般来说,这个全局变量是线程安全的;若有多个线程同时执行写操作,一般都需要考虑线程同步,否则就可能影响线程安全。
注意:为什么后者不安全?
if(car == null){
car = new Car();
}
如果同时实例化多个对象,假设c1,c2,若c1刚运行到if(car == null)被暂时结束了,进而实例化c2,此时car为null,执行car = new Car();实例了一个对象;而c1回复中断,也执行了car = new Car();就获取了多个不同的对象,就不再符合单例模式,因此是不安全的。