单例模式:则在这个类被创建后,只可能产生一个实例供外部访问,并且提供一个全局的访问点。
核心的知识点:
1.private构造方法,防止通过new关键字,实例化出实例来。
2.再其内部产生该类的实例化对象,并用public static修饰。
3.写一个static方法,返回该实例对象。
一共介绍四种方式,前三种了解就可以了,随后一种为单例模式中的最优解。
1.饿汉式Singleton
//优点:写法简单,线程安全 //缺点:实例一直存在于内存中,会造成内存的浪费 public class SingletonTest { //构造方法写成private 防止通过 new SingletonTest()来创建实例 private SingletonTest(){ } //饿汉式,用fianl关键字修饰 private static final SingletonTest instance = new SingletonTest(); public static SingletonTest getSingletonInstance(){ return instance; } } 2.饱汉式Singleton
//优点:写法简单,某些情况下节约内存 //缺点:并发的环境下会出现多个SingletonTest2实例,非线程安全 public class SingletonTest2 { //构造方法写成private 防止通过 new SingletonTest()来创建实例 private SingletonTest2(){ } //饱汉式,没有使用final关键字 private static SingletonTest2 instance; public static SingletonTest2 getSingletonInstance(){ if(instance == null) new SingletonTest2(); return instance; } }3. 饱汉式Singleton:使用synchronize关键字优化了非线程安全的问题
//缺点:同步方法频繁调用,效率低 public class SingletonTest3 { //构造方法写成private 防止通过 new SingletonTest()来创建实例 private SingletonTest3(){ } //饱汉式,没有使用final关键字 private static SingletonTest3 instance; //调用时再初始化SingletonTest3,使用synchronized避免多线程访问时,可能造成重的复初始化问题) public static synchronized SingletonTest3 getSingletonInstance(){ if(instance == null) new SingletonTest3(); return instance; } } 4.单例模式的最优解
//单例模式的最优方案 public class SingletonTest4 { //构造方法写成private 防止通过 new SingletonTest()来创建实例 private SingletonTest4(){ } //饱汉式,没有使用final关键字 //用volatile修饰的变量,线程在每次使用变量的时候,都会读取变量修改后的最新的值 //使用volatile保证了多线程访问时instance变量的可见性,避免了instance初始化时其他变量属性还没赋值完时,被另外线程调用 private static volatile SingletonTest4 instance; public static SingletonTest4 getSingletonInstance(){ //instance不等于null时,直接返回对象,提高运行效率 if(instance == null) //同步代码块(对象未初始化时,使用同步代码块,保证多线程访问时对象在第一次创建后,不再重复被创建) synchronized (SingletonTest4.class) { instance = new SingletonTest4(); } return instance; } 纸上得来终觉浅。。。
快乐学习,快乐编程!