晚上睡不着,那就把设计模式再看一下吧,顺便写一篇文章,如果有问题,欢迎斧正,谢谢。
首先介绍一下单例模式。也是最长用的。通常加载配置啊都会用到。
源码地址:https://github.com/DeveloperZJQ/scalavsjava/tree/master/src/main/java/designpatterns/singleton
直接上代码
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
/**
* @author happy
* @since 2020-10-09
* 饿汉式 方式一 : 静态常量饿汉式
*/
public class StarvationSingleton {
private static final StarvationSingleton starvationInstance = new StarvationSingleton();
private StarvationSingleton() {
}
;
public static StarvationSingleton getInstance() {
return starvationInstance;
}
/**
* read local file
*/
public Properties getFileConfig(String fileName) {
Properties pro = new Properties();
InputStream resourceAsStream = StarvationSingleton.class.getClassLoader().getResourceAsStream(fileName);
try {
pro.load(resourceAsStream);
} catch (IOException e) {
e.printStackTrace();
}
return pro;
}
public static void main(String[] args) {
StarvationSingleton instance1 = StarvationSingleton.getInstance();
StarvationSingleton instance2 = StarvationSingleton.getInstance();
System.out.println(instance1==instance2);
System.out.println(instance1);
System.out.println(instance2);
}
}
说明:饿汉式,上来就new,不用关系到底实例是否存在,多线程情况下不会用到该方法。
直接上代码
懒汉式单例懒加载,不能解决线程安全问题、
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
/**
* @author happy
* @since 2020-10-09
* 懒汉式 方式二
*/
public class LazyOf2LockSingleton {
private static LazyOf2LockSingleton lazyOf2LockSingleton;
private LazyOf2LockSingleton() {
}
;
public static LazyOf2LockSingleton getInstance() {
if (lazyOf2LockSingleton == null) {
lazyOf2LockSingleton = new LazyOf2LockSingleton();
}
return lazyOf2LockSingleton;
}
//get local file config
public Properties getFileConfig(String fileName) {
Properties pro = new Properties();
InputStream resourceAsStream = LazyOf2LockSingleton.class.getClassLoader().getResourceAsStream(fileName);
try {
pro.load(resourceAsStream);
} catch (IOException e) {
e.printStackTrace();
}
return pro;
}
public static void main(String[] args) {
Properties fileConfig = getInstance().getFileConfig("demo.properties");
System.out.println(fileConfig);
}
}
说明:多线程下不能用该方式。
直接上代码
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
/**
* @author happy
* @since 2020-10-09
*/
public class StaticInnerSingleton {
private StaticInnerSingleton(){};
private static class StaticInnerSingletonInstance{
private static final StaticInnerSingleton instance = new StaticInnerSingleton();
}
public static StaticInnerSingleton getInstance(){
return StaticInnerSingletonInstance.instance;
}
//get local file config
public Properties getFileConfig(String fileName){
Properties pro = new Properties();
InputStream resourceAsStream = LazyOf2LockSingleton.class.getClassLoader().getResourceAsStream(fileName);
try {
pro.load(resourceAsStream);
} catch (IOException e) {
e.printStackTrace();
}
return pro;
}
}
说明:适用于多线程,该方式在多个框架源码中存在,它兼顾了懒汉式的懒加载,又保证了多线程下只存在一个单例。
直接上代码
懒汉式单例-双重锁
解决线程安全问题、同时解决懒加载问题
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
/**
* @author happy
* @since 2020-10-09
* 懒汉式 方式二
*/
public class LazyOf2LockSingleton {
//volatile 保证可见性
private static volatile LazyOf2LockSingleton lazyOf2LockSingleton;
private LazyOf2LockSingleton() {
}
;
public static LazyOf2LockSingleton getInstance() {
if (lazyOf2LockSingleton == null) {
synchronized (LazyOf2LockSingleton.class) {
if (lazyOf2LockSingleton == null) {
lazyOf2LockSingleton = new LazyOf2LockSingleton();
}
}
}
return lazyOf2LockSingleton;
}
//get local file config
public Properties getFileConfig(String fileName) {
Properties pro = new Properties();
InputStream resourceAsStream = LazyOf2LockSingleton.class.getClassLoader().getResourceAsStream(fileName);
try {
pro.load(resourceAsStream);
} catch (IOException e) {
e.printStackTrace();
}
return pro;
}
public static void main(String[] args) {
Properties fileConfig = getInstance().getFileConfig("demo.properties");
System.out.println(fileConfig);
}
}
说明:充分保证多线程下安全,兼具懒加载优势。
直接上代码
1)线程安全问题。因为Java虚拟机在加载枚举类的时候会使用ClassLoader的方法,这个方法使用了同步代码块来保证线程安全。
2)避免反序列化破坏对象,因为枚举的反序列化并不通过反射实现。
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
/**
@author happy
@since 2020-10-09
*/
public enum EnumSingleton {
INSTANCE;
//get local file config
public Properties getFileConfig(String fileName) {
Properties pro = new Properties();
InputStream resourceAsStream = LazyOf2LockSingleton.class.getClassLoader().getResourceAsStream(“demo.properties”);
try {
pro.load(resourceAsStream);
} catch (IOException e) {
e.printStackTrace();
}
return pro;
}
public static void main(String[] args) {
Properties fileConfig = INSTANCE.getFileConfig(“”);
System.out.println(fileConfig);
}
}
说明:天然保证线程安全,代码简单,推荐使用。