SingletonObject1.java
package com.test.synchonized2;
/**
* 饿汉模式的单例,缺点:不是懒加载,所以会造成即使没有该类实例没有被使用,
* 也会有实例被加载出来,会出现资源浪费
*/
public class SingletonObject1 {
private static SingletonObject1 instance = new SingletonObject1();
private SingletonObject1() {
// empty
}
public static SingletonObject1 getInstance() {
return instance;
}
}
SingletonObject2.java
package com.test.synchonized2;
/**
* 懒汉模式的单例(懒加载方式),缺点:在多线程环境中调用,可能会出现创建多个实例,
* 导致不是真正的单例模式
*/
public class SingletonObject2 {
private static SingletonObject2 instance;
private SingletonObject2() {
// empty
}
public static SingletonObject2 getInstance() {
if (instance == null) {
instance = new SingletonObject2();
}
return instance;
}
}
SingletonObject3.java
package com.test.synchonized2;
/**
* 同步方法+懒汉模式的单例(懒加载),缺陷:能解决多线程环境中懒加载造成的多个实例问题,
* 但是也同样导致获取实例方法变为了“串行化”,在多线程环境中获取单例速度变慢,影响性能
*/
public class SingletonObject3 {
private static SingletonObject3 instance;
private SingletonObject3() {
// empty
}
public synchronized static SingletonObject3 getInstance() {
if (instance == null) {
instance = new SingletonObject3();
}
return instance;
}
}
SingletonObject4.java
package com.test.synchonized2;
/**
* 同步方法+双重验证(double check)的懒汉单例模式(懒加载)
* 缺陷:即使进行了double check ,但是因为没有使用volatile修饰,
* 所以无法保证可见性和有序性:volatile关键字可以保证【可见性】和【有序性】
* 因为没有保证有序性,所以可能出现空指针异常
*/
public class SingletonObject4 {
private static SingletonObject4 instance;
private Object obj1;
private Object obj2;
private SingletonObject4() {
// empty
/**
* 因为没有保证可见性和有序性,所以在初始化过程中会出现重排序,
* instance 已经创建好了,但是 obj1和obj2还没创建好,
* 第二个线程走到过程①的时候,以为instance创建好了,所以就返回了 instance 实例
* 但是调用到instance的 obj1或者obj2引用类型的属性进行操作时候就可能出现 空指针异常
*/
obj1 = new Object();
obj2 = new Object();
}
public static SingletonObject4 getInstance() {
if (instance == null) { // ①
synchronized (SingletonObject4.class) {
if (instance == null) {
instance = new SingletonObject4();
}
}
}
return instance;
}
}
SingletonObject5.java
package com.test.synchonized2;
public class SingletonObject5 {
private static volatile SingletonObject5 instance;
private SingletonObject5() {
// empty
}
public static SingletonObject5 getInstance() {
if (instance == null) {
synchronized (SingletonObject5.class) {
if (instance == null) {
instance = new SingletonObject5();
}
}
}
return instance;
}
}
SingletonObject6.java
package com.test.synchonized2;
/**
* 利用的策略:静态类只会被JVM创建一次
*/
public class SingletonObject6 {
private SingletonObject6() {
// empty
}
private static class InstanceHolder{
private static final SingletonObject6 instance = new SingletonObject6();
}
public static SingletonObject6 getInstance() {
return InstanceHolder.instance;
}
}
SingletonObject7.java
package com.test.synchonized2;
/**
* 最好的单例模式需要满足三点要求:
* ① 懒加载模式
* ② 在多线程环境中实例也是只会被创建一次,实现单例
* ③ 在多线程环境中获取单例实例时,性能与在单线程环境中使用一致,不存在“串行化”或者“阻塞问题”
*/
public class SingletonObject7 {
private SingletonObject7() {
// empty
}
/**
* 利用枚举两个特性实现单例模式:
* ① 枚举类是线程安全的
* ② 枚举的构造方法只会被装载一次
*/
private enum Singleton {
INSTANCE;
private final SingletonObject7 instance;
Singleton() {
instance = new SingletonObject7();
}
public SingletonObject7 getInstance() {
return instance;
}
}
public static SingletonObject7 getInstance() {
return Singleton.INSTANCE.getInstance();
}
public static void main(String[] args) {
for (int i = 0; i <100 ; i++) {
new Thread(new Runnable() {
@Override
public void run() {
System.out.println(SingletonObject7.getInstance());
}
}).start();
}
}
}