一、单例模式
1.单例分两种:
饿汉式 和 懒汉式
饿汉式:
package com.chess.test;
/**
*
* 饿汉模式的单例
* @author chess
*
*/
public final class SignleObjectHungry
{
private static SignleObjectHungry signleObjHun = new SignleObjectHungry();
private SignleObjectHungry()
{
}
public static SignleObjectHungry getInstance()
{
return signleObjHun;
}
}
懒汉式
package com.chess.test;
/**
* 懒汉式单例模式
* @author chess
*
*/
public final class SingleObjectLazy
{
private static SingleObjectLazy signleObjLazy = null;
private SingleObjectLazy()
{
}
public static SingleObjectLazy getInstance()
{
if(null == signleObjLazy)
{
signleObjLazy = new SingleObjectLazy();
}
return signleObjLazy;
}
}
由于单例存在线程安全问题,所以要解决的话
对于
饿汉式线程安全
package com.chess.test;
/**
* 饿汉式单例线程安全
* @author chess
*
*/
public final class SingleObjectHungryAndThreadSafe
{
private static SingleObjectHungryAndThreadSafe signleObj =
new SingleObjectHungryAndThreadSafe();
private SingleObjectHungryAndThreadSafe()
{
}
/**
* 加同步锁方法实现线程安全
*
* 此方法存在 性能开销 大
*
* @return
*/
public synchronized static SingleObjectHungryAndThreadSafe getInstance()
{
return signleObj;
}
}
懒汉式线程安全
package com.chess.test;
/**
* 懒汉式单例 和 线程安全
*
* @author chess
*
*/
public final class SingleObjectLazyAndThreadSafe
{
private static SingleObjectLazyAndThreadSafe singleObj = null;
private SingleObjectLazyAndThreadSafe()
{
}
// public synchronized static SingleObjectLazyAndThreadSafe getInstance()
// {
// if(null == singleObj)
// {
// singleObj = new SingleObjectLazyAndThreadSafe();
// }
//
// return singleObj;
//
// }
// 细化粒度,提高性能 提高线程并发度
//双重检查锁机制
public static SingleObjectLazyAndThreadSafe getInstance()
{
if (null == singleObj)
{
synchronized (SingleObjectHungryAndThreadSafe.class)
{
if (null == singleObj)
{
singleObj = new SingleObjectLazyAndThreadSafe();
}
}
}
return singleObj;
}
//至此 线程安全 已经感觉狠完美了。
//多线程中,如果 线程A 执行到第 30 行,此时对象为空,则进入初始化对象,
// 然而初始化对象需要时间,
// 此时 线程B 也执行到第 30 行 , 此时对象已经初始化未完成, 但是地址已经存在。
// 则 线程B 将获取一个未完成的 对象。
}
完美的解决方案
package com.chess.test;
/**
* 单例模式线程安全的完美状态
* 新的设计模式
* 使用内部类 JLS会保证这个类的线程安全
* (完全使用 JAVA 虚拟机的机制进行同步保证,且 没有同步的关键字)
* @author chess
*
*/
public class SingleObjectThreadSafeNoSync
{
/**
* 以内部类实现懒加载(懒汉)
*
* 初始化这个内部类的时候 JLS 保证这个类的线程安全
* @author cWX181783
*
*/
private static class SingletonHolder
{
public final static SingleObjectThreadSafeNoSync singleObject =
new SingleObjectThreadSafeNoSync();
}
public static SingleObjectThreadSafeNoSync getInstance()
{
return SingletonHolder.singleObject;
}
}