java单例模式
原创
©著作权归作者所有:来自51CTO博客作者wx63186321c235c的原创作品,请联系作者获取转载授权,否则将追究法律责任
目录
1、通过静态内部类实现
2、饿汉式
3、懒汉式
4、调用
单例的三种模式
1、通过静态内部类实现
2、饿汉式
3、懒汉式
1、通过静态内部类实现
package day07.java8.pattern.singleton;
/*
通过静态内部类实现
*/
public class Demo03 {
// 构造器,私有,不能被new
private Demo03(){}
// ClassHolder属于静态内部类,在加载类Demo03的时候,只会加载内部类ClassHolder,
// 但是不会把内部类的属性加载出来
private static class ClassHolder{
// 这里执行类加载,是jvm来执行类加载,它一定是单例的,不存在线程安全问题
// 这里不是调用,是类加载,是成员变量
private static final Demo03 demo03 =new Demo03();
}
public static Demo03 getInstance(){//第一次调用getInstance()的时候赋值
return ClassHolder.demo03;
}
}
单例模式,分3部分。
1、构造器私有
2、new 一个实例,保证这个实例只能被new一次
3、把这个实例return出去。
------------------
1、构造器私有,不能被new
2、静态内部类,当Demo3类加载的时候,只会加载到静态内部类ClassHolder,不会把
静态内部类ClassHolder的属性加载出来
3、Demo03 demo03 是静态对象,在new的时候才会被加载
2、饿汉式
总结就是:
1、构造器私有,不能被new
2、提供一个静态的属性,属性就是这个类new出来的一个实例。
静态static ,类在jvm加载的时候,会执行一次,之后就不会再执行了。
3、将实例return出去。
package day07.java8.pattern.singleton;
/**
* 饿汉式
* 单例模式:
* 实例只有一个(无论怎么做,只有一个实例)
* 1、第一步,先私有构造器,不允许new
* 1、只要new,就会产生一个新的实例,解决办法1,构造器私有,这样就不能new了
*/
public class Demo01 {
// 私有的静态方法,new Demo01
// static 静态方法,可以直接被类调用
// static 静态方法,只有在类加载的时候才会执行一次,以后就不执行了(代码只会执行一次)
// 这个属性的方法,不需要调用,在加载类的时候,就会自己执行(static 静态方法)
private static Demo01 demo01 = new Demo01();
private Demo01() {
}
// 公开的获取实例的方法
public static Demo01 getInstance(){
return demo01;
}
}
缺点:
在jvm类加载的时候,就会创建这个实例。如果这个实例很大,就会影响性能。
3、懒汉式
package day07.java8.pattern.singleton;
/*
懒汉式
1、第一步,先私有构造器,不允许new
缺点:
致命,如果两个线程同时调用了getInstance(),那么会产生两个对象,线程不安全问题
解决线程安全问题,加锁
如果把锁直接加在getInstance()方法上,效率会慢,且没有办法解决
两个if,双重判断,demo02为null就去排队,不为空就直接return,不需要排队
(个人觉得,就是把判断放到了锁前边)
外面的if,就是为了提高效率
里面的if,就是实现单例模式
*/
public class Demo02 {
// demo02 是一个静态的成员变量,不是方法(这里先不赋值)
//类加载的时候,没有给demo02赋值
private static Demo02 demo02;
private Demo02(){}
public static Demo02 getInstance(){//第一次调用getInstance()的时候赋值
// 提高效率,不为空,不进入锁池
if(demo02==null){
// 加锁,第一次为null的时候,线程安全
synchronized (Demo02.class){
// 保证单例
if(demo02==null){
demo02=new Demo02();
}
}
}
return demo02;
}
}
4、调用
package day07.java8.pattern.singleton;
public class TestDemo {
public static void main(String[] args) {
Demo01 demo01 =Demo01.getInstance();
Demo01 demo011 = Demo01.getInstance();
System.out.println("demo011 = " + demo011);
System.out.println("demo01 = " + demo01);
System.out.println("=========");
Demo02 demo02 =Demo02.getInstance();
Demo02 demo022 =Demo02.getInstance();
System.out.println("demo022 = " + demo022);
System.out.println("demo02 = " + demo02);
}
}
---------------------------------------------------------------------
5、通过静态内部类实现,讲解
1、首先要求这个单例模式的这个类,不能被new。
如果一个类,可以通过new来创建对象。则每次new 创建出来的对象,哈希code码是不一样的,则每次new出来的都是不同的对象。
所以要求,这个单例模式的类不能被new。我们把构造器私有就好了。
构造器私有,只能在本类里访问。