一:单例模式作用: 核心作用:保证一个类只有一个实例,并且提供一个访问该实例的全局访问点。 二:单例模式的优点: 1、由于单例模式只生成一个实例,减少了系统的性能开销,当一个对象的产生需要比较多的 资源时,如读取配置,产生其他依赖对象时,则可以通过在应用启动时直接产生一个单例 对象,然后永久驻留内存的方式来解决。 2、单例模式可以在系统设置全局的访问点,优化共享资源访问,例如可以设计一个单例类 负责所有数据表的映射处理。 三:常见的5中单例模式实现方式 主要: 1、饿汉式(线程安全、调用效率高、但是不能延时加载) 2、懒汉式(线程不安全、调用效率不高、但是可以延时加载) 其他: 1、双重检测锁式(由于JVM底层内部模型的原因,偶尔会出问题,不建议使用) 2、静态内部类式(线程安全、调用效率高、可以延时加载) 3、枚举单例(线程安全、调用效率高、但不能延时加载) 不需要延时加载:枚举好于饿汉 需要延时加载:静态内部类好于懒汉
1、饿汉式:
2、懒汉式:package com.chen.Singleton; /** * 饿汉式单例模式 *1、私有化构造器 *2、创建对象 *3、提供静态方法获得实例对象 * 不用加synchronized,饿汉式天生线程安全,但不能延时加载,加载类时就实例化对象 * @author Administrator * */ public class SingletonDemo01 { // 2、创建对象 private static SingletonDemo01 instance = new SingletonDemo01(); // 1、私有化构造器 private SingletonDemo01() { } // 3、提供静态方法获得实例对象 public static SingletonDemo01 getInstance() { return instance; } }
package com.chen.Singleton; /** * 懒汉式单例模式,和恶汉式差不多,不同点在于, * 需要加synchronized来保证单例,可以延时加载 * @author Administrator * */ public class SingletonDemo02 { private static SingletonDemo02 instance; private SingletonDemo02() { } public static synchronized SingletonDemo02 getInstance() { if(instance == null) { instance = new SingletonDemo02(); } return instance; } }
3、静态内部类式:
package com.chen.Singleton; /** * 静态内部类实现单例模式 * 兼并了饿汉式和懒汉式的优点,线程安全,效率高,可以延时加载 * @author Administrator * */ public class SingletonDemo03 { private static class SingletonInstance { private static final SingletonDemo03 instance = new SingletonDemo03(); } private SingletonDemo03() { } public static SingletonDemo03 getInstance() { return SingletonInstance.instance; } }
4、枚举实现单例模式:
package com.chen.Singleton; /** * 枚举实现单例模式 * 唯一缺点:不能延时加载 * 相比其他单例模式:解决了反射、序列化带来的问题 * @author Administrator * */ public enum SingletonDemo04 { // 枚举类型,本身就是一个单例模式 INSTANCE; // 添加自己的操作.... public void test() { System.out.println("你好啊!!!"); } }
测试:
package com.chen.Singleton; /** * 测试单例模式 * @author Administrator * */ public class Test { public static void main(String[] args) { test01(); } public static void test01() { SingletonDemo01 instance = SingletonDemo01.getInstance(); SingletonDemo01 instance2 = SingletonDemo01.getInstance(); System.out.println(instance); System.out.println(instance2); // 枚举类型的调用 SingletonDemo04 instance3 = SingletonDemo04.INSTANCE; System.out.println(instance3); instance3.test(); } }
测试各种单例模式的效率:
package com.chen.Singleton; import java.util.concurrent.CountDownLatch; /** * 测试各种单例模式的效率 * CountDownLatch:同步辅助类 * countDown() 当前线程调用该方法,则计数器减一(建议放在finally中执行) * await() 调用该方法会一直阻塞线程,直到计数器为0 * * 测试结果: * 懒汉式用时比恶汉多大约两个数量级 * @author Administrator * */ public class Test_Effective { public static void main(String[] args) throws Exception { long startTime = System.currentTimeMillis(); int threadNum = 10; // 计数器初始值为10 // 不加final内部类中无法访问 final CountDownLatch count = new CountDownLatch(threadNum); // 创建10个线程 for(int i = 0; i < threadNum; i++) { new Thread(new Runnable(){ @Override public void run() { for(int i = 0; i < 10000000; i++) { // 01变为02就可以测试第二种的效率了。 SingletonDemo01 instance = SingletonDemo01.getInstance(); } // 每个线程执行完成,计数器减一 count.countDown(); } }).start(); } // main线程等待,直到计数器为0才开始往下执行 count.await(); long endTime = System.currentTimeMillis(); System.out.println("耗时:"+(endTime - startTime)+"ms"); } }
本文介绍了单例模式的作用及优点,并详细解析了五种常见的单例模式实现方式,包括饿汉式、懒汉式、双重检测锁式、静态内部类式和枚举单例。
1502

被折叠的 条评论
为什么被折叠?



