Day2

tech2025-09-17  2

Java设计模式:一共有23种设计模式 。 参考http://c.biancheng.net/design_pattern/

单例模式定义:

所谓单例,就是整个程序有且只有一个实例。该类负责创建自己的对象,同时确保只有一个对象被创建。好处就是一个类你只能创建一个实例对象可以节约内存开销。一般查那个用于在工具类的实现。(之前讲过的静态方法也可以用于工具类的实现)。单例模式特点:1.构造器私有2.持有自己类型的属性3.对外提供获取实例的静态方法一般单例模式分为两大类:懒汉模式、饿汉模式。详细分其实有懒汉、饿汉、双检索、内部类模式、枚举实现等方式。

A、懒汉模式

懒汉模式 延迟初始化,在调用方法获取时候的时候才会实例化对象 线程不安全的,严格意义上不是单例模式

public class SingleTonTest01 { //持有自己类型的属性 private static SingleTonTest01 singleTonTest01; //构造器私有 private SingleTonTest01 () { } private static SingleTonTest01 getSingleton() { if (singleTonTest01 ==null) { singleTonTest01 = new SingleTonTest01(); } return singleTonTest01; // TODO Auto-generated method stub} public static void main(String[] args) { SingleTonTest01 single = SingleTonTest01.getSingleton(); SingleTonTest01 single2 = SingleTonTest01.getSingleton(); System.out.println(single == single2); } }

​B、饿汉模式

线程安全,比较常用,但是容易产生垃圾,应为饿汉模式是一开始加载类的时候就初始化了实例

public class SingleTonTest02 { //持有自己类型的属性 //由于static修饰,只在类加载的时候加载一次 private static SingleTonTest02 singleTonTest02 = new SingleTonTest02(); //构造方法私有化 private SingleTonTest02() { } //提供对外的静态方法获取实例 private static SingleTonTest02 getSingleton() { return singleTonTest02; } public static void main(String[] args) { SingleTonTest02 singleton = SingleTonTest02.getSingleton(); SingleTonTest02 singleTon2 = SingleTonTest02.getSingleton(); System.out.println(singleton == singleTon2); } }

懒汉模式和饿汉模式区别:懒汉是非线程安全,饿汉式线程安全的。加载时间不同:懒汉模式是一开始不实例化对象,通过调用方法的时候才会实例化对象,饿汉模式:类加载的时候就实例化了对象,容易造成资源浪费综合两者各自的优缺点,可以使用双检索模式,综合了懒汉式和饿汉式的优缺点整合而成C、双检锁模式(双重校验锁)双检索也称为双重校验锁,综合了懒汉和饿汉两者的优缺点整合而成

C、双检索实现单例模式

public class SingletonTest03 { //提供自己类型的对象 volatile保证了锁可见 private volatile static SingletonTest03 singletonTest03; //构造类型私有 private SingletonTest03 () { } //提供对外的静态获取实例的方法 public static SingletonTest03 gesingleton() { if (singletonTest03 ==null) { synchronized (SingletonTest03.class) { singletonTest03 = new SingletonTest03(); } } return singletonTest03; } public static void main(String[] args) { SingletonTest03 s = SingletonTest03.gesingleton(); SingletonTest03 s2 =SingletonTest03.gesingleton(); System.out.println(s == s2); } }

双检索模式:进行了两次判断,第一次判断是为了避免不要的实例,第二次是为了进行线程同步,避免多线程问题。Singleton()创建对象的时候,jvm种可能会重新排序,在多线程存在风险。使用volatile关键字可以当线程改变其值后通知其他线程以改变并且不会被jvm重新排序,解决该问题D、内部类实现单例模式

D、内部类模式

public class SingletonTest04 { //提供私用构造方法 private SingletonTest04 () { } //提供静态对外的获取实例对象方法 public static SingletonTest04 getInstance() { return Inner.instance; } public static class Inner{ //取得自己本身类型的对象 private static final SingletonTest04 instance = new SingletonTest04() ; } public static void main(String[] args) { SingletonTest04 singletonTest04 = SingletonTest04.getInstance(); SingletonTest04 singletonTest042 =SingletonTest04.getInstance(); System.out.println(singletonTest04 == singletonTest042); } }

​只有第一次调用getInstance()方法式,虚拟机才加载Inner()并初始化instance.只有一个线程获得对象的初始化锁,其他线程无法进行初始化,保证了对象的唯一性【目前次方式式所有单例模式种最值得推荐的一种方法】

E、枚举实现单例模式

最新回复(0)