单例模式,保证一个类只有一个实例,并且自行实例化,并想整个系统提供这个实例。
一、注意事项:
1、构造函数可以用private修饰
2、单例对象实例化过程,在多线程过程中,需要保证不会产生多个实例。
3、单例模式需要注意垃圾回收机制,如果我们一个单例对象在内存中长久不使用,jvm会认为这是一个垃圾对象,在CPU资源空闲情况下对对象进行清理。
二、应用场景 :业务逻辑上限定不能多例只能单例的情况
三、实现方式:
1、饿汉模式
优点:实现简单,类加载就实现了实例化,没有现成同步问题
缺点:类加载就实现了实例化,如果实例化对象一直不使用,会造成内存浪费
例子:
public class SinglePattern {
public static final SinglePattern single =new SinglePattern();
private SinglePattern(){}
public static SinglePattern getSingle(){
return single;
}
public void doSomething() {System.out.println("i am singlepattern"); }
public static void main(String[] args) {
SinglePattern.getSingle().doSomething();
}
}
2、简单懒汉模式(线程不安全)
优点:实现简单,第一次调用才会初始化,避免内存浪费
缺点:不支持多线程,高并发情况下会出现多个实例化对象
例子:
public class UnsafeSinglePattern {
public static UnsafeSinglePattern single ;
private UnsafeSinglePattern(){}
public static UnsafeSinglePatterngetSingle()
{
if(single==null){single = new UnsafeSinglePattern();}
return single;
}
public void doSomething()
{
System.out.println("i am unsafesingle pattern");
}
}
3、懒汉模式,线程安全
优点:第一次调用才会初始化,避免内存浪费,支持多线程
缺点:需要加锁来保证单例的初始化,会影响效率
例子:
public class SafeSinglePattern {
public static SafeSinglePattern single ;
private SafeSinglePattern(){}
public static synchronizedSafeSinglePattern getSingle()
{
if(single==null)
{
single= new SafeSinglePattern();
}
return single;
}
public void doSomething()
{
System.out.println("i am safesingle pattern");
}
public static void main(String[] args) {
SafeSinglePattern.getSingle().doSomething();
}
}
4、懒汉模式,双重检验锁
优点:支持多线程,并且采用双检测机制,保持高性能
缺点:实现复杂
例子:
public class SafeSinglePattern {
public static SafeSinglePattern single ;
private SafeSinglePattern(){}
public static SafeSinglePattern getSingle()
{
if(single==null)
{
synchronized(SafeSinglePattern.class)
{
if(single ==null)
{
single = new SafeSinglePattern();
}
}
}
return single;
}
public void doSomething()
{
System.out.println("i am safesingle pattern");
}
public static void main(String[] args) {
SafeSinglePattern.getSingle().doSomething();
}
}
}
注意:如果在多线程情况下尽量使用双重检验锁的模式。
网友评论