说到单例OA信用盘源码出售,网上教程和很多人信手拈来:

说到单例OA信用盘源码出售QQ2952777280【话仙源码论坛】hxforum.com,网上教程和很多人信手拈来:

public class Single
{
private volatile static Single instance;

private Single()
{
    System.out.println("创建单例");
}
public static Single getInstance()
{
    if (instance == null)
    {
        synchronized (Single.class)
        {
            if (instance == null)
            {
                instance = new Single();
            }
        }
    }
    return instance;
}

}
自信满满,称之为懒汉加载模式,言之节省内存,用时才会自动创建。在我看来,这种写法完全是错误的,愚蠢至极,这不是***子放屁,这是脱完裤子再提取裤子再放屁。

正确写法就是最简单的:

public class Single
{
private static Single instance=new Single();

private Single()
{
    System.out.println("创建单例");
}
public static Single getInstance()
{
    return instance;
}

}

下面驳斥所谓的省内存。

public class SingleTest
{

public static void main(String[] args) throws  Exception
{
    System.out.println("启动线程");
    System.in.read();
}

}
首先,不用单例时,难道别的写法就会加载单例?没有引用使用单例类时,当然都不会加载单例。

看图,并不会加载创建单例,控制台也不会输出创建单例。

其次,既然预定要使用单例,那么都会加载创建一次。

public class SingleTest
{

public static void main(String[] args) throws  Exception
{
    System.out.println("启动线程");
    Single.getInstance();
    System.in.read();
}

}
看图,无论哪种模式单例都会被引用加载

是不是用synchronized创建单例就没有用处了呢?

并不是,synchronized是用于解决多线程访问问题。带参数的单例创建才应该使用懒汉模式

因为并不能预期,什么时候参数被传入。简单模式下并不清楚传入什么参数,或参数对象未初始化。

public class Single
{
private volatile static Single instance ;
public Single(Context context)
{
System.out.println("创建单例");
}
public static Single getInstance(Context context)
{
if (instance == null)
{
synchronized (Single.class)
{
if (instance == null)
{
instance = new Single(context);
}
}
}
return instance;
}
}

为什么说这个是为了解决多线程访问呢,先看如果不加锁会发生什么

复制代码
public class Single
{
private static Single instance ;
public Single(Context context)
{
System.out.println("创建单例");
}
public static Single getInstance(Context context)
{
if (instance == null)
{
instance = new Single(context);
}
return instance;
}
}
复制代码

public class SingleTest
{

public static void main(String[] args) throws Exception
{
    ExecutorService pool = Executors.newCachedThreadPool();
    ArrayList<Callable<Void>> runners=new   ArrayList<>();
    for(int i=0;i<10;i++)
    {
        runners.add(()->{
            Single.getInstance(new Context());
            return null;
        });
    }
    System.out.println("启动线程");
    pool.invokeAll(runners);
    pool.shutdown();
    System.in.read();
}

}

总结,无参构造单例无需复杂的加入synchronized,而未确定的传参单例需要加synchronized保证多线程访问安全。

思考,如果传入的参数确定,怎么写才最优呢?下面类似写法是否合理:

public class Single
{
private static Single instance =new Single(Context.instance);

public Single(Context context )
{
    System.out.println("创建单例");
}
public static Single getInstance( )
{

    return instance;
}

}

复制代码br/>@WebListener
public class MyServletContextListener implements ServletContextListener {

public void contextDestroyed(ServletContextEvent sce)  { 

}

public void contextInitialized(ServletContextEvent sce)  { 
    Single.getInstance(sce);
}

}

猜你喜欢

转载自blog.51cto.com/14023195/2301294
今日推荐