Java设计模式
Java设计模式
单例模式
什么是单例模式
每使用一次new关键字创建一个对象,就在内存中新增加一个内存地址,如果创建的次数多了,那可是很耗费内存空间的。单例模式就是来解决这样的问题的,单例模式保证一个对象在程序中只创建一次,那么在内存中也就只有一份。
单例模式简单来说就是保证某一个类在程序中只实例化一次,以后调用这个类时始终是指向同一个内存地址的类。
单例模式的分类
单例模式的创建分为懒汉式、饿汉式两种模式。饿汉式就是当类以加载时就创建这个的实例,懒汉式是当第一次调用时才会创建这个类的实例;
饿汉式
public class StudentSingle1 {
private static final StudentSingle1 studentSingle1 = new StudentSingle1();
private StudentSingle1() {
}
public static StudentSingle1 getInstance() {
return studentSingle1;
}
}
懒汉式
懒汉式只有在使用时才创建对象,而且只创建一次。在懒汉单例模式中如果只是使用if语句来判断对象是否创建,那么会出现线程安全问题;
多线程不安全
// 多线程不安全
public class StudentSingle2 {
private static StudentSingle2 studentSingle2;
private StudentSingle2() {
}
public static StudentSingle2 getInstance() {
if (studentSingle2 == null) {
/**
* 线程1执行到这里时,cpu切换线程2也执行到这里,
* 此时的线程被1迫暂停,
* 线程2创建对象后,线程1开启创建对象,创建了两个对象
* 这样就出现多线程安全问题
*/
studentSingle2 = new StudentSingle2();
}
return studentSingle2;
}
}
多线程安全
双重判断:也就是进行两次判断,但在进第二次判断时会采用synchronized来进行线程排队,会影响一定的性能;
public class StudentSingle2 {
private static StudentSingle2 studentSingle2;
private static boolean isInstance = false;
//构造方法中进行判断是为了防止反射破坏单例模式
//isInstance为false表示对象还未创建,如果为true表示对象已创建,可以抛一个运行异常,表示不可在创建对象。
private StudentSingle2() {
synchronized (StudentSingle2.class) {
if (isInstance) {
throw new RuntimeException("不可重复创建此对象");
}
isInstance = true;
}
}
/**
*双重判断
*/
public static StudentSingle2 getInstanceSyn() {
if (studentSingle2 == null) {
synchronized (StudentSingle2.class) {
if (studentSingle2 == null) {
studentSingle2 = new StudentSingle2();
}
}
}
return studentSingle2;
}
}
静态内部类可解决synchronized带来的性能影响问题。被static关键字修饰的都会在类加载时被创建,也是唯一的一份内存地址。
public class StudentSingle2 {
private static StudentSingle2 studentSingle2;
private static boolean isInstance = false;
//构造方法中进行判断是为了防止反射破坏单例模式
//isInstance为false表示对象还未创建,如果为true表示对象已创建,可以抛一个运行异常,表示不可在创建对象。
private StudentSingle2() {
synchronized (StudentSingle2.class) {
if (isInstance) {
throw new RuntimeException("不可重复创建此对象");
}
isInstance = true;
}
}
/**
* 静态内部类保证多线程安全
*
* @return
*/
public static StudentSingle2 getinstanceClass() {
return studentSingle2;
}
/**
* 静态内部类解决多线程单例模式问题
*/
static class StudentStatic {
private static StudentSingle2 STUDENTSINGLE2 = new StudentSingle2();
}
}