单例模式总计有多种实现方式: 懒汉式、饿汉式、注册登记式(枚举)、静态内部类式、反序列化式
其中CountDownLatch的使用可参考: https://blog.csdn.net/industry2018/article/details/86662143
1. 懒汉式
package com.industry.design;
import java.util.concurrent.CountDownLatch;
public class LazySingleton {
private static Object obj = new Object();
private LazySingleton() {
}
private static LazySingleton INSTANCE;
public static LazySingleton getInstance() {
if (INSTANCE == null) {
synchronized (obj) {
if (INSTANCE == null) {
INSTANCE = new LazySingleton();
}
}
}
return INSTANCE;
}
public static void main(String[] args) {
CountDownLatch latch = new CountDownLatch(100);
for (int i = 0; i < 100; i++) {
new Thread() {
@Override
public void run() {
try {
latch.await();
LazySingleton instance = LazySingleton.getInstance();
System.out.println(System.currentTimeMillis() + ":" + instance);
} catch (Exception e) {
e.printStackTrace();
}
}
}.start();
latch.countDown();
}
}
}
2. 饿汉式
package com.industry.design;
import java.util.concurrent.CountDownLatch;
public class HungrySingleton {
private HungrySingleton() {
}
private static HungrySingleton INSTACNE = new HungrySingleton();
public static HungrySingleton getInstance() {
return INSTACNE;
}
public static void main(String[] args) {
CountDownLatch latch = new CountDownLatch(100);
for (int i = 0; i < 100; i++) {
new Thread() {
@Override
public void run() {
try {
latch.await();
HungrySingleton instance = HungrySingleton.getInstance();
System.out.println(System.currentTimeMillis() + ":" + instance);
} catch (Exception e) {
e.printStackTrace();
}
}
}.start();
latch.countDown();
}
}
}
3. 注册登记式
package com.industry.design;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CountDownLatch;
/**
* 注册登记式
*/
public class RegisterSingleton {
private static Object obj = new Object();
private RegisterSingleton() {
}
private static Map<String, RegisterSingleton> instanceMap = new ConcurrentHashMap<String, RegisterSingleton>();
public static RegisterSingleton getInstance(String name) throws Exception {
if (null == name || "".equals(name.trim())) {
name = RegisterSingleton.class.getName();
}
if (instanceMap.get(name) == null) {
synchronized (obj) {
if (instanceMap.get(name) == null) {
System.out.println("map中无对象,进行put操作");
instanceMap.put(name, RegisterSingleton.class.newInstance());
}
}
}
return instanceMap.get(name);
}
public static void main(String[] args) {
CountDownLatch latch = new CountDownLatch(100);
for (int i = 0; i < 100; i++) {
new Thread() {
@Override
public void run() {
try {
latch.await();
RegisterSingleton instance = RegisterSingleton.getInstance("");
System.out.println(System.currentTimeMillis() + ":" + instance);
} catch (Exception e) {
e.printStackTrace();
}
}
}.start();
latch.countDown();
// map中无对象,进行put操作
// 1548647134425:com.industry.design.RegisterSingleton@52c6e53a
// 1548647134425:com.industry.design.RegisterSingleton@52c6e53a
// 1548647134425:com.industry.design.RegisterSingleton@52c6e53a
// 1548647134425:com.industry.design.RegisterSingleton@52c6e53a
// 1548647134425:com.industry.design.RegisterSingleton@52c6e53a
}
}
}
3.1 枚举式
package com.industry.design;
import java.util.concurrent.CountDownLatch;
public enum EnumRegisterSingleton {
RED(0, "red"), WHITE(1, "white"), BLACK(2, "black"), GREEN(3, "green");
private int value;
private String name;
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
private EnumRegisterSingleton(int value, String name) {
this.value = value;
this.name = name;
}
public static EnumRegisterSingleton getEnumRegisterSingleton(String name) {
EnumRegisterSingleton[] values = EnumRegisterSingleton.values();
for (EnumRegisterSingleton enumRegisterSingleton : values) {
if (enumRegisterSingleton.getName().equals(name)) {
return enumRegisterSingleton;
}
}
return null;
}
public static void main(String[] args) {
CountDownLatch latch = new CountDownLatch(100);
for (int i = 0; i < 100; i++) {
new Thread() {
@Override
public void run() {
try {
latch.await();
EnumRegisterSingleton instance = EnumRegisterSingleton.getEnumRegisterSingleton("red");
System.out.println(System.currentTimeMillis() + ":" + instance.getName() + "|" + instance.getValue());
} catch (Exception e) {
e.printStackTrace();
}
}
}.start();
latch.countDown();
// 1548646831673:red|0
// 1548646831673:red|0
// 1548646831673:red|0
// 1548646831673:red|0
// 1548646831673:red|0
}
}
}
4. 静态内部类式
package com.industry.design;
import java.util.concurrent.CountDownLatch;
public class InnerSingleton {
private InnerSingleton() {
}
// 通过静态内部类获取实例
public static InnerSingleton getInstance() {
return MyHandler.INSTANCE;
}
private static class MyHandler {
private static InnerSingleton INSTANCE = new InnerSingleton();
}
public static void main(String[] args) {
CountDownLatch latch = new CountDownLatch(100);
for (int i = 0; i < 100; i++) {
new Thread() {
@Override
public void run() {
try {
latch.await();
InnerSingleton instance = InnerSingleton.getInstance();
System.out.println(System.currentTimeMillis() + ":" + instance);
} catch (Exception e) {
e.printStackTrace();
}
}
}.start();
latch.countDown();
}
}
}
5. 反序列化式
package com.industry.design;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
public class SerializableSingleton implements Serializable {
private static final long serialVersionUID = 1961528585861392465L;
private SerializableSingleton() {
}
private static SerializableSingleton INSTANCE = new SerializableSingleton();
public static SerializableSingleton getInstance() {
return INSTANCE;
}
/**
* 反序列化方式必须添加该方法,否则对象不是同一个
*
* @return
*/
private Object readResolve() {
return INSTANCE;
}
public static void main(String[] args) {
try {
FileOutputStream fout = new FileOutputStream("serializableSingleton");
ObjectOutputStream oos = new ObjectOutputStream(fout);
SerializableSingleton instance = SerializableSingleton.getInstance();
oos.writeObject(instance);
oos.flush();
oos.close();
System.out.println(instance);
FileInputStream fin = new FileInputStream("serializableSingleton");
ObjectInputStream ois = new ObjectInputStream(fin);
SerializableSingleton serializableSingleton = (SerializableSingleton) ois.readObject();
ois.close();
System.out.println(serializableSingleton);
System.out.println(serializableSingleton == instance);
// com.industry.design.SerializableSingleton@5c647e05
// com.industry.design.SerializableSingleton@5c647e05
// true
} catch (Exception e) {
e.printStackTrace();
}
}
}