标签:并且 error asi string stat 线程同步 wear loading sed
采取一定的方法,保证整个软件系统中,对某个类只能存在一个对象实例,并且该类只提供一个取得其对象实例的方法
getInstance
class Singleton {
private Singleton() {
}
private final static Singleton instance = new Singleton();
public static Singleton getInstance() {
return instance;
}
}
同一
class Singleton {
private Singleton() {
}
private static Singleton instance;
static {
//在静态代码块中创建单例对象
instance = new Singleton();
}
public static Singleton getInstance() {
return instance;
}
}
Lazy loading
作用,但是只能在单线程下使用if(singleton == null)
判断语句块,还未来得及往下执行,另一个线程也通过了这个判断语句,这时便会产生多个实例,导致线程不安全class Singleton {
private Singleton() {
}
private static Singleton instance;
public static Singleton getInstance() {
//使用到该方法时才去创建
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
class Singleton {
private Singleton() {
}
private static Singleton instance;
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
class Singleton {
private Singleton() {
}
private static Singleton instance;
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
instance = new Singleton();
}
}
return instance;
}
}
常用
class Singleton {
private Singleton() {
}
/**
* volatile让修改对其他线程立即可见
*/
private static volatile Singleton instance;
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
常用
class Singleton{
private Singleton() {
}
/**
* 1.Singleton装载时,SingletonInstance不会被装载
* 2.调用getInstance时,内部类才会装载,类装载时线程安全
*/
private static class SingletonHolder {
private static final Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance() {
return SingletonHolder.INSTANCE;
}
}
常用
enum Singleton{
/**
*定义一个枚举元素,代表了Singleton的一个实例
*/
INSTANCE;
public void operation() {
}
}
常用
class Singleton {
private Singleton() {
}
private final static String INSTANCE = "INSTANCE";
/**
* 要用ConcurrentHashMap
*/
private static Map<String, Singleton> map = new ConcurrentHashMap<>();
public static Singleton getInstance() {
Singleton singleton = map.get(INSTANCE);
if (singleton == null) {
singleton = new Singleton();
map.put(INSTANCE, singleton);
}
return singleton;
}
}
1.JDK
java.lang.Runtime
public Class Runtime{
//饿汉式
private static Runtime currentRuntime = new Runtime();
public static Runtime getRuntime() {
return currentRuntime;
}
}
2.Spring
org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#getSingleton(java.lang.String, boolean)
//double-check
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
synchronized (this.singletonObjects) {
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
singletonObject = singletonFactory.getObject();
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
return singletonObject;
}
public class ReflectSingletonTest{
public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
Class<Singleton> clazz = Singleton.class;
Constructor constructor = clazz.getDeclaredConstructor();
constructor.setAccessible(true);
Singleton instance = Singleton.getInstance();
Singleton reflectInstance = (Singleton) constructor.newInstance();
System.out.println(instance == reflectInstance);
}
}
class Singleton {
private Singleton(){
//防止反射攻击, 不加上该段,上述运行结果为false
if (SingletonHolder.INSTANCE != null) {
throw new IllegalStateException();
}
}
private static class SingletonHolder {
private static final Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance() {
return SingletonHolder.INSTANCE;
}
}
public class SeriaSingletonTest {
public static void main(String[] args) throws Exception {
Singleton instance = Singleton.getInstance();
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("D:/seria.txt"));
oos.writeObject(instance);
oos.flush();
oos.close();
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("D:/seria.txt"));
Singleton instance2 = (Singleton) ois.readObject();
//返回false
System.out.println(instance == instance2);
}
}
class Singleton implements Serializable {
private Singleton() {
}
private static Singleton instance = new Singleton();
public static Singleton getInstance() {
return instance;
}
}
加上readResolve
方法
class Singleton implements Serializable {
private Singleton() {
}
private static Singleton instance = new Singleton();
public static Singleton getInstance() {
return instance;
}
/**
* 防止反序列化时单例被破坏
* @return
*/
private Object readResolve() {
return instance;
}
}
java.io.ObjectStreamClass#invokeReadResolve
Object invokeReadResolve(Object obj)
throws IOException, UnsupportedOperationException
{
requireInitialized();
//1.有readResolve方法时进入
if (readResolveMethod != null) {
try {
//2.反射调用readResolve方法的返回值,即instance
return readResolveMethod.invoke(obj, (Object[]) null);
} catch (InvocationTargetException ex) {
Throwable th = ex.getTargetException();
if (th instanceof ObjectStreamException) {
throw (ObjectStreamException) th;
} else {
throwMiscException(th);
throw new InternalError(th); // never reached
}
} catch (IllegalAccessException ex) {
// should not occur, as access checks have been suppressed
throw new InternalError(ex);
}
} else {
throw new UnsupportedOperationException();
}
}
相关代码 https://github.com/liberxk/blog-code/tree/master/desing-pattern
参考:
1.《研磨设计模式》
2.图解Java设计模式 韩顺平
标签:并且 error asi string stat 线程同步 wear loading sed
原文地址:https://www.cnblogs.com/liberxk/p/11440116.html