单例模式定义:
单例模式确保某个类只有一个实例。保证了全局对象的唯一性。
优点:该类只存在一个实例,节省系统资源,对于需要频繁创建销毁的对象,使用单例模式可以提高系统性能。
缺点:不能外部实例化(new),调用人员不清楚调用哪个方法获取实例。
单例模式的特点:
1)单例模式只能有一个实例。
2)单例类必须创建自己的唯一实例。
3)单例类必须向其他对象提供这一实例。
实现方式:
方法一(饿汉式):
public class Singleton{ private static Singleton singleton=new Singleton(); private Singleton(){ } public static Singleton getInstance(){ return singleton; } }
优点:线程安全,获取实例速度快。
缺点:类加载即初始化实例,内存浪费。
方法二(静态代码块)
public class Singleton{ private static Singleton singleton=null; private Singleton(){ } static{ singleton=new Singleton(); } public static Singleton getInstance(){ return singleton; } }
此方法与方法一类似,优缺点一致。
方法三(单线程懒汉式)
public class Singleton{ private static Singleton singleton=null; private Singleton(){ } public static Singleton getInstance(){ if(singleton==null){ singleton=new Singleton(); } return singleton; } }
优点:在获取实例的方法中,进行实例的初始化,节省系统资源。
缺点:非线程安全,当多个线程访问getInstance()时,可能产生多个实例。
方法四(多线程懒汉式)
//同步锁 public class Singleton{ private static Singleton singleton=null; private Singleton(){ } public synchronized static Singleton getInstance(){ if(singleton==null){ singleton=new Singleton(); } return singleton; } }
优点:线程安全。
缺点:每次获取实例都要加锁,耗费资源,其实只要实例已经生成,以后获取就不需要再锁了。
//双重检查锁 public class Singleton{ private static Singleton singleton=null; private Singleton(){ } public static Singleton getInstance(){ if(singleton==null){ synchronized(Singleton.class){ if(singleton==null){ singleton=new Singleton(); } } } return singleton; } }
优点:线程安全,进行双重检查,保证只在实例未初始化前进行同步,效率高。
缺点:实例非空判断,耗费一定资源。
方法五(静态内部类)
public class Singleton{ private Singleton(){ } private static class SingletonHolder{ private static Singleton singleton=new Singleton(); } public static Singleton getInstance(){ return SingletonHolder.singleton; } }
优点:静态内部类不会在单例加载时就加载,而是在调用getInstance()方法时才进行加载。这样既避免了同步带来的性能损耗,又能延迟加载。
方法六(枚举)
public enum Singleton{ INSTANCE; private Singleton(){ } }
其功能完整,使用简洁、无偿地提供了序列化机制,在面对复杂的序列化或者反序列化攻击时仍然可以绝对防止多次实例化等,单元素的枚举类型,是实现Singleton的最佳方法。
1)代码简单
2)天然线程安全
3)自由序列化,防止反射生成实例
实例应用
枚举
public enum DataSourceEnum{ DATASOURCE; private DBConnection connection=null; private DataSourceEnum(){ this.connection=new DBConnection(); } public DBConnection getConnection(){ return connection; } }
DBConnection类
public class DBConnection{ }
测试类
public class Solution{ public static void main(String[] args){ DBConnection con1 = DataSourceEnum.DATASOURCE.getConnection(); DBConnection con2 = DataSourceEnum.DATASOURCE.getConnection(); System.out.println(con1 == con2); } }
posted on
浙公网安备 33010602011771号