单例模式
/**
* 1、饿汉式
* 在调用之前会首先实例化.
* 优点:写法简单,避免了线程同步问题。
* 缺点:在调用之前就会实例化,没有达到Lazy loading的效果。如果自始至终都没有使用过这个实力,就会造成内存浪费。
*
* 注意: 1、加载顺序,先静态再动态,先属性再方法,先上后下。
* 2、构造方法要是私有化的,
* 3、属性要用final修饰,不能够被覆盖。
* @author wangfy
*/
public class EHanShi {
private final static EHanShi eHanShi = new EHanShi();
private EHanShi() {
}
public static EHanShi getInstance() {
return eHanShi;
}
}
/**
* 2、饿汉式:静态代码块实现
* 该方式同上一个相同,但是实例化使用了静态代码块来实现。
* @author wangfy
*/
public class EHanShi2 {
private static EHanShi2 eHanShi ;
static{
eHanShi = new EHanShi2();
}
private EHanShi2(){}
public static EHanShi2 getInstance() {
return eHanShi;
}
}
/**
* 3、懒汉式:线程不安全
* 调用的时候才会实例化
* 优点:达到Lazy loading的效果
* 缺点:线程不安全,如果多线程情况下,如果一个线程进入if判断,另一个线程也进入if判断,还没有往下执行,那么就会产生多个实例
* @author wangfy
*/
public class LanHanShi {
private static LanHanShi lanHanShi;
private LanHanShi() {
}
public static LanHanShi getInstance() {
if (lanHanShi == null) {
lanHanShi = new LanHanShi();
}
return lanHanShi;
}
}
/**
* 4、懒汉式:线程安全,同步方法
* 在获取实例的方法上加上同步锁。
* 优点:即达到Lazy loading的效果,又解决了线程不安全的问题。
* 缺点:效率低下,每个线程在获取类的时候,执行getInstance都要进行同步。
* 需要改进:而且该方法实现过一次实例化就行了。后面获取实例不需要进入同步直接return就可以了。
* @author wangfy
*/
public class LanHanShi2 {
private static LanHanShi2 lanHanShi;
private LanHanShi2() {
}
public static synchronized LanHanShi2 getInstance() {
if (lanHanShi == null) {
lanHanShi = new LanHanShi2();
}
return lanHanShi;
}
}
/**
* 5、懒汉式:双重检查 Double-Check
* 摒弃同步方法,使用了同步代码块。进行了两次if判断。这样实例化只执行了一次,后面如果再要访问直接return。
* 优点:即达到Lazy loading的效果,又解决了线程不安全的问题,效率相对较高。
* @author wangfy
*/
public class LanHanShi3 {
private static LanHanShi3 lanHanShi;
private LanHanShi3() {
}
public static LanHanShi3 getInstance() {
if (lanHanShi == null) {
synchronized (LanHanShi3.class) {
if (lanHanShi == null) {
lanHanShi = new LanHanShi3();
}
}
}
return lanHanShi;
}
}
/**
* 6、懒汉式:静态内部类
* 该方式跟饿汉式采用的机制类似,但是有不同。两只都是使用了类加载机制来保证实例化时只有一个线程。
* 不同的地方在饿汉式方式是只要LanHanShi4类被装载就会实例化,没有懒加载的作用,
* 而静态内部类方式在LanHanShi4类被装载时并不会立即实例化,而是在需要实例化时,
* 调用getInstance方法,才会装载LanHanInstance类,从而完成LanHanShi4的实例化。
* 类的静态属性只会在第一次加载类的时候初始化,所以在这里,JVM帮助我们保证了线程的安全性,在类进行初始化时,别的线程是无法进入的。
* 优点:避免了线程不安全,延迟加载,效率高。
* @author wangfy
*/
public class LanHanShi4 {
private LanHanShi4() {}
private static class LanHanInstance{
private static final LanHanShi4 LANHANSHI4 = new LanHanShi4();
}
public static LanHanShi4 getInstance(){
return LanHanInstance.LANHANSHI4;
}
}