1.Singleton最多只有一个实例,在不考虑反射强行突破访问限制的情况下。
2.保证了并发访问的情况下,不会发生由于并发而产生多个实例。
3.保证了并发访问的情况下,不会由于初始化动作未完全完成而造成使用了尚未正确初始化的实例。
1 双重加锁。
/**
* @author lmc
* @Email huyang@126.com
* @date 2018年11月28日
* (1) 双重校验的单例模式 (双重加锁)
*/
public class Singletonsys {
//一个私有的静态的对象
private static Singletonsys singletonsys;
//private static volatile Singletonsys singletonsys;
//一个私有的构造函数
private Singletonsys(){};
//给出一个共用的静态方法返回一个单一实例
public static Singletonsys getInstance(){
if (singletonsys == null) {
synchronized(Singletonsys.class) {
if (singletonsys==null) {
singletonsys = new Singletonsys();
}
}
}
return singletonsys;
}
2 静态的内部类作为单例
/**
* @author lmc
* @Email huyang@126.com
* @date 2018年11月28日
* 内部内的方式创建单实例
*/
public class InnerSingleton {
//私有构造函数
private InnerSingleton(){};
//提供对外服务的实例
public static InnerSingleton getInstance(){
return Innercla.innerSingleton;
}
//内部类的实例
private static class Innercla{
private static InnerSingleton innerSingleton = new InnerSingleton();
}
3 饿汉式加载单例
/**
* @author lmc
* @Email huyang@126.com
* @date 2018年11月28日
* 饿汉式加载单例
*/
public class Singletioner {
//私有静态变量实例,最简洁的一种了
private static Singletioner singletioner = new Singletioner();
private Singletioner(){}
public static Singletioner getInstance(){
return singletioner;
}
public static void main(String[] args) {
ExecutorService executorService = Executors.newCachedThreadPool();
for (int i = 0; i < 100; i++) {
executorService.execute(new Runnable() {
@Override
public void run() {
System.out.println(getInstance());
}
});
}
}
单例 : 就是这些类,在整个应用中,同一时刻,有且只能有一种状态。
1.静态实例,带有static关键字的属性在每一个类中都是唯一的。
2.限制客户端随意创造实例,即私有化构造方法,此为保证单例的最重要的一步。
3.给一个公共的获取实例的静态方法,注意,是静态的方法,因为这个方法是在我们未获取到实例的时候就要提供给客户端调用的,所以如果是非静态的话,那就变成一个矛盾体了,因为非静态的方法必须要拥有实例才可以调用。
4.判断只有持有的静态实例为null时才调用构造方法创造一个实例,否则就直接返回。