北风设计模式课程---5、单例模式
一、总结
一句话总结:
一个实例:保证一个类、只有一个实例存在,
全局访问:提供能对该实例加以访问的全局访问方法。
1、为什么要使用单例模式呢?
节约资源(比如数据库连接),
实际情况(一个军队只能有一个最高指挥官)
2、单例模式使用场景?
在多个线程之间,比如servlet环境,共享同一个资源或者操作同一个对象
在整个程序空间使用全局变量,共享资源
大规模系统中,为了性能的考虑,需要节省对象的创建时间等等。
3、单例模式实现的方式?
饿汉式:唯一的那份自己的实例先被创建了(比如加final关键词,比如弄成静态的),返回的时候直接返回这个 唯一的实例
懒汉式:唯一的那份自己的实例在用的时候才被创建
双重检查:检测了两遍if(person == null):在解決懒汉式多线程时候单例可能不唯一的情况下,不必把整个方法锁起来,只用把new对象锁起来就好,这样效率高点:另一遍检测发送在多个进程穿越第一次检测的情况:外层检测提高效率,内层检查保证单例
4、单例模式的编程实现原理?
构造函数私有化,并且提供一个全局的静态方法来获取类的实例
饿汉式:唯一的那份自己的实例先被创建了(比如加final关键词,比如弄成静态的),返回的时候直接返回这个 唯一的实例
懒汉式:唯一的那份自己的实例在用的时候才被创建
双重检查:检测了两遍if(person == null):在解決懒汉式多线程时候单例可能不唯一的情况下,不必把整个方法锁起来,只用把new对象锁起来就好,这样效率高点:另一遍检测发送在多个进程穿越第一次检测的情况:外层检测提高效率,内层检查保证单例
5、为什么单例模式中获取类的实例的方法要是静态的?
如果不是静态,那要获取对象才能调用这个方法,而构造函数私有化的情况下,我们是没办法获取这个类的对象的
6、如何在保证类中只有 自己的 唯一一份实例?
实例声明成静态的
实例用final关键词限定
7、在多线程中,饿汉式和懒汉式能否保证只有一份实例?
饿汉式能保证:因为只有最开始声明的那一份
懒汉式不一定能保证
8、如何解决多线程中懒汉式不能保证 实例只有一份的问题?
加上同步关键词:synchronized:public static synchronized Person3 getPerson()
public class Person3 {
private String name;
private static Person3 person;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
//构造函数私有化
private Person3() {
}
//提供一个全局的静态方法,使用同步方法
public static synchronized Person3 getPerson() {
if(person == null) {
person = new Person3();
}
return person;
}
}
9、饿汉式单例模式实现实例?
一开始就创建好了唯一的那份实例:private static final Person2 person = new Person2();
public class Person2 {
private String name;
private static final Person2 person = new Person2();
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
//构造函数私有化
private Person2() {
}
//提供一个全局的静态方法
public static Person2 getPerson() {
if(person == null) {
person = new Person2();
}
return person;
}
}
10、懒汉式单例模式实现实例?
需要调用实例的时候 来判读有没有实例,需不需要生成
public class Person3 {
private String name;
private static Person3 person;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
//构造函数私有化
private Person3() {
}
//提供一个全局的静态方法,使用同步方法
public static synchronized Person3 getPerson() {
if(person == null) {
person = new Person3();
}
return person;
}
}
11、双重检查单例模式实现实例?
检测了两遍if(person == null):在解決懒汉式多线程时候单例可能不唯一的情况下,不必把整个方法锁起来,只用把new对象锁起来就好,这样效率高点:另一遍检测发送在多个进程穿越第一次检测的情况:外层检测提高效率,内层检查保证单例
public class Person4 {
private String name;
private static Person4 person;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
//构造函数私有化
private Person4() {
}
//提供一个全局的静态方法
public static Person4 getPerson() {
if(person == null) {
synchronized (Person4.class) {
if(person == null) {
person = new Person4();
}
}
}
return person;
}
}
12、单例模式中,饿汉式,懒汉式,双重检查的优缺点?
饿汉式:无论是否多线程,永远单例,但是效率偏低
懒汉式:效率高,但是多线程情况下无法保证单例
双重检查:效率相对高,并且能够在多线程情况下保证单例
13、final关键字的作用是什么?
(1)final修饰的变量是常量。
(2)final修饰的方法不能被重写
(3)final修饰的类不能被继承。(就无所谓方法重写的问题了)
(4)final修饰的对象的地址(引用)不能改变,但是对象的值可以改变。
二、内容在总结中