单例模式
1.单例模式概念:单例模式就是一个类只有一个实例。
2.单例模式的特点:
(1)单例类只能有一个实例。
(2)单例类必须自己创建自己的唯一实例。
(3)单例类必须给所有其他对象提供这一实例
3.单例模式的具体实现
(1)饿汉模式
public class Singleton{
private static Singleton instance=new Singleton();
private Singleton(){}
pulic static Singleton getInstance(){
return instance;
}
}
(2)懒汉模式
public class Singleton{
private static Singleton instance;
private Singleton(){}
public static Singleton getInstance(){
if(instance==null)
return instance=new Singleton();
else
return instance;
}
}
懒汉和饿汉的区别:
a.饿汉模式线程安全,懒汉模式在多线程会出现线程安全问题需要手动实现线程安全
b.懒汉模式在运行的时候 获取对象比较慢,但是加载类的时候比较快,但是饿汉模式是在运行的时候获取对象较快,
加载类的时候慢。
c.从实现方式来讲他们最大的区别就是懒汉式是延时加载
懒汉模式我们怎么实现线程安全呢????
(1)加锁
public class Singleton{
private static Singleton instance;
private Singleton(){}
public static sychronized Singleton getInstance(){
if(instance==null)
return instance=new Singleton();
else
return instance;
}
}
特点:实现了线程安全,但是由于synchronized限制了整个getInstance方法,
而我们只是希望在new Singleton()时进行加锁,因此这种写法会导致效率不高。
(2)改良版
public class Singleton{
private static Singleton instance;
private Singleton(){}
public static sychronized Singleton getInstance(){
if(instance==null)
sychronized(Singleton.class){
if(instance==null)
instance=new Singleton();
}
return instance;
}
}
这就是所谓的双检锁机制,很可惜这种写法在很多平台和优化编译器中无法编译通过
(3)兼容版
public class Singleton{
private Singleton(){}
private static class Inner{
private static Singleton instanceHolder=new Singleton();
}
public static Singleton getInstacen(){
return Inner.instanceHolder;
}
}
由于内部类在编译完成后也是一个单独的class文件,因此在不使用的情况下Inner类是不会被加载的。同时,JVM保证在类加载的过程中static代码块在多线程或者单线程下都正确执行,且仅执行一次。解决了延迟加载以及线程安全的问题。