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();
        }
    }