线程涉及单例模式

/**
 * 单例模式涉及的两个问题
 * 
 * @author 罗摩衔那
 *
 */
/*
 * 恶汉式
 * 优点:当类被加载的时候,已经创建好了一个静态的对象,因此,是线程安全的
 * 缺点:这个对象还没有被使用就被创建出来了
 */
class Single
{
    private static final Single s=new Single();//
    private Single() {}//私有无参构造方法
    public static Single getInstance()
    {
        return s;
    }
}
/*
 * 懒汉式
 * 优点:按需加载对象,只有对象被使用的时候才会被创建
缺点:这种写法不是线程安全的,例如当第一个线程执行判断语句if(s = null)时, 
第二个线程执行判断语句if(s = null),接着第一个线程执行语句test = new Test(), 
第二个线程也执行语句test = new Test(),在这种多线程环境下,可能会创建出来两个对象
 */
class Singler
{
    private static Singler s=null;
    private Singler() {};
    public static /*synchronized*/ Singler getInstance()
    {        /*
             * 一.-->线程0 -->线程1 当线程0进入创建对象
             *   线程1进入不用判断也创建对象--出问题
             * 二.当给函数加上同步性质synchronized后,线程进入,不为空
             *   也就不判断,那么就不用创建对象,问题解决
             * 三.下面加同步锁是为了线程安全问题
             *   最外面再加一次判断是为了效率问题
             */
        if(s==null)
        {
        synchronized(Singler.class)
        {
            if(s==null)
            s=new Singler();    
        }
        }
        return s;
    }
    }

public class SingleDemo {
   public static void main(String[] args) {
    System.out.println("Hello World!");
}
}

第三种情况时:进入线程0,判断是否为null,获得线程锁占位,再判断是null创建对象,返回一个s.

假设线程0释放执行权,线程1判断完后,是进不来的--因为0线程的执行资格还没释放,接着释放执资格.

接着线程1进入,判断为null,获得线程锁占位,再次判断s不为空.

原文地址:https://www.cnblogs.com/zjm1999/p/9925073.html