写一个单例的类

就是写一个实例化一次的类
即把构造私有化,外部无法实例化他。通过调用他的静态方法,判断是否实例化了,未实例化则实例化并返回,已实例化则返回已实例化的。

一:

/**
 * 基于双重检查锁定的单例模式
 * @author zongzhimin
 *
 */
public class SingleDog4{

    /**
     * 在错误示范2的基础上给instance加 volatile进行修饰
     * volatile可以保证instance的可见性禁止上个错误示例的那种重排序
     */
    private static volatile SingleDog4  instance    = null;

    private SingleDog4(){
    }

    public static SingleDog4 getInstance(){//双重检查防止多线程下出问题
        if (null == instance){// 1
            synchronized (SingleDog4.class){
                if(null == instance) {
                    instance = new SingleDog4();//2
                }

            }
        }
        return instance;
    }

    public void say(){
        System.out.println("Single all the way");
    }
}

二:

/**
 * 基于静态内部类的单列模式
 * @author zongzhimin
 *
 */
public class SingleDog6{

    private SingleDog6(){
    }

    private static class InstanceHolder{
        final static SingleDog6 instance = new SingleDog6();
    }
    public static SingleDog6 getInstance(){
        return InstanceHolder.instance;
    }

    public void say(){
        System.out.println("Single all the way");
    }
}

性能不好:

/**
 * 这个性能不好
 * @author zongzhimin
 *
 */
public class SingleDog{

    private static SingleDog    instance    = null;

    private SingleDog(){
    }

    public static SingleDog getInstance(){//这里每次获取实例都要先获取锁,性能不好
        synchronized (SingleDog.class){
            if (null == instance){
                instance = new SingleDog();
            }
            return instance;
        }
    }

    public void say(){
        System.out.println("Single all the way");
    }
}

错误示范1:

/**
 * 错误示范1
 * @author zongzhimin
 *
 */
public class SingleDog2{

    private static SingleDog2   instance    = null;

    private SingleDog2(){
    }
    /**
     * 这里做了改进将静态快放在里面但是这是错误的!!!
     * 多线程下A线程到1, B线程到2 -->(A判断instance==null、正好B线程执行完2实例化一次)-->(这时A线程会进入静态快再实例化一次。单例失败)
     *      
     * @return
     */
    public static SingleDog2 getInstance(){
        if (null == instance){// 1
            synchronized (SingleDog2.class){
                instance = new SingleDog2();//2
            }
        }
        return instance;
    }

    public void say(){
        System.out.println("Single all the way");
    }
}

错误示范2:

/**
 * 错误示范2
 * @author zongzhimin
 *
 */
public class SingleDog3{

    private static SingleDog3   instance    = null;

    private SingleDog3(){
    }
    /**
     * 这里在错误示范的基础上做了改进增加一次进入静态快的判断!!!在块里再判断一次,避免错误示范2里面的再次实例化
     * 但这依然是不正确的:
     * 对于2操作: 可以分为  一:分配SingleDog3对象所需空间  二:初始化SingleDog3对象 三:将对象引用写入instance对象
     * 由于重排序在临界区(静态快内的操作可以重排序)所以2操作可能是:一、三、二。
     * 因此:
     *      线程A进入静态快且进行一、三、二的 三这一步(还未走二实例化SingleDog3但是已先给instance变量赋地址)
     *  而另一线程B进入1,发现instance不为null,然后return instance,此时线程A还未走完er,即SingleDog3还未实例化,程序出错
     *      
     * @return
     */
    public static SingleDog3 getInstance(){
        if (null == instance){// 1
            synchronized (SingleDog3.class){
                if(null == instance) {
                    instance = new SingleDog3();//2
                }

            }
        }
        return instance;
    }

    public void say(){
        System.out.println("Single all the way");
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值