package com.MySingletonTest;
/**
* Created by liuxuanjie on 2020/01/08.
* 单例模式的创建,保证多线程安全
*
* ps:
* 这是第一种方式,直接在类加载的时候创建一次
*/
public class MySingleton1
{
//私有静态自身引用
private static MySingleton1 singleton = new MySingleton1();
//私有构造方法
private MySingleton1() {
}
//静态外部调用入口
public static MySingleton1 getSingleton()
{
return singleton;
}
}
package com.MySingletonTest;
/**
* Created by liuxuanjie on 2020.1.8.
* 单例模式的实现,保证多线程的线程安全
*
* ps:
* 跟第一种方式一样,只是写法不同
* 仍旧利用的是类加载器的单一性加载
*/
public class MySingleton2 {
private static MySingleton2 singleton = null;
//静态代码段,类加载时期会执行一次
static
{
singleton = new MySingleton2();
}
//私有构造方法
private MySingleton2()
{
}
//静态外部入口
public static MySingleton2 getSingleton()
{
return singleton;
}
}
package com.MySingletonTest;
/**
* Created by liuxuanjie on 2020.1.8.
* 单例模式的实现,保证多线程安全
*
* ps
* 采用静态内部类的方法
* 这种方法对前两种方法做出了优化
* 实现了,真正用的时候才真正实例化
*
* 解释说明:
* 1. 外部类初次加载,会初始化静态变量、静态代码块、静态方法,但不会加载内部类和静态内部类。
* 2. 实例化外部类,调用外部类的静态方法、静态变量,则外部类必须先进行加载,但只加载一次。
* 3. 直接调用静态内部类时,外部类不会加载。
*/
public class MySingleton3
{
//私有静态内部类
private static class InnerSingletonHold
{
private static MySingleton3 singleton = new MySingleton3();
}
//私有静态方法
private MySingleton3()
{
}
public static MySingleton3 getSingleton()
{
return InnerSingletonHold.singleton;
}
}
package com.MySingletonTest;
import java.util.concurrent.atomic.AtomicReference;
/**
* Created by liuxuanjie on 2020.1.8.
* 实现单例模式,保证多线程安全
*
* ps:
* 使用CAS方法,实现原子性操作
*/
public class MySingleton4
{
/**
* 原子引用
* 使用java的并发包下的的atomic操作。
*/
private static AtomicReference<MySingleton4> atomicReference = new AtomicReference<>();
/**
* 私有构造方法
*/
private MySingleton4()
{
}
/**
* CAS操作实现单例模式下的多线程安全
* ps:
* 优点:就是CAS操作的优点,自旋无阻塞
* 缺点:消耗CPU,并且在实例化那一行代码会有很多无用实例化对象
* 可以理解为,很多实例化对象被创建,只不过CAS操作的结果是只保留一个
*
* @return 单例模式唯一真实引用
*/
public static MySingleton4 getSingleton()
{
//CAS操作一般配合无限循环进行自旋
while(true)
{
//先获得当前的状态
MySingleton4 singleton = atomicReference.get();
//如果当前状态不为空,证明单例已经实例化,直接返回
if (null != singleton)
{
return singleton;
}
else
{
//单例引用为空,实例化
singleton = new MySingleton4();
//CAS原子性操作,更新引用,指向实例化对象
//此刻发生竞争,有且只能有一个线程更新成功
if (atomicReference.compareAndSet(null, singleton))
{
return singleton;
}
}
}
}
}
package com.MySingletonTest;
/**
* Created by liuxuanjie on 2020.1.8.
* 实现单例模式,保证多线程安全
*
* ps:
* 这个方法也比较常见,双判断减少Synchronized的性能消耗
*/
public class MySingleton5
{
/**
* 私有静态的自身引用
*/
private volatile static MySingleton5 singleton = null;
/**
* 私有构造方法
*/
private MySingleton5()
{
}
/**
* 双判断减少synchronized的作用次数,以此减少性能消耗
* @return 单例模式的唯一真实实例化对象的引用
*/
public static MySingleton5 getSingleton()
{
if(singleton == null)
{
synchronized (MySingleton5.class)
{
if(singleton == null)
{
singleton = new MySingleton5();
}
}
}
return singleton;
}
}