singleton单例实现
来源:互联网 发布:订货单软件 编辑:程序博客网 时间:2024/05/17 01:33
第一种方式:同步实现
package design.pattern.singleton;
/**
* 同步保证线程安全,如果并发严重,会导致性能问题
*
* @author SunOlny
*
*/
public class SingletonStrategyTwo {
private static SingletonStrategyTwo singletonStrategyTwo = null;
private SingletonStrategyTwo() {
}
public static synchronized SingletonStrategyTwo getInsttance() {
if (singletonStrategyTwo == null) {
singletonStrategyTwo = new SingletonStrategyTwo();
}
return singletonStrategyTwo;
}
}
第二种实现:利用加载器的特性
package design.pattern.singleton;
import java.io.Serializable;
/**
* classloader机制能保证线程安全但是无法实现懒加载
*
* @author SunOnly
*
*/
public class SingletonStrategyStaticAttribute implements Serializable {
/**
*
*/
private static final long serialVersionUID = 6319892805778631527L;
private static SingletonStrategyStaticAttribute sinletonStrategyOne = new SingletonStrategyStaticAttribute();
private SingletonStrategyStaticAttribute() {
}
public static SingletonStrategyStaticAttribute getInstance() {
return sinletonStrategyOne;
}
}
第三种方式:解决懒加载的问题,我们使用内部的静态类进行优化
package design.pattern.singleton;import java.io.Serializable;
/**使用内部类初始化单例,让其形成懒加载
* @author SunOlny
*
*/
public class SingletonStartegyInnerClass implements Serializable {
/**
*
*/
private static final long serialVersionUID = 4458426835180723296L;
private SingletonStartegyInnerClass() {
}
private static class Handler {
private static final SingletonStartegyInnerClass singletonStartegyInnerClass = new SingletonStartegyInnerClass();
}
public static SingletonStartegyInnerClass getInstance() {
return Handler.singletonStartegyInnerClass;
}
}
package design.pattern.singleton;
/**
*
* 双重验证模式,只能是J2SE1.5之后才能保证线程安全
*
* @author SunOlny
*
*/
public class SingletonStrategyThree {
private static volatile SingletonStrategyThree singletonStrategyThree = null;
private SingletonStrategyThree() {
}
public static SingletonStrategyThree getInsttance() {
if (singletonStrategyThree == null) {
synchronized (SingletonStrategyThree.class) {
if (singletonStrategyThree == null) {
singletonStrategyThree = new SingletonStrategyThree();
}
}
}
return singletonStrategyThree;
}
}
上面的方式如果是有实现序列化,那么反序列化时就无法保证类的单例特性了。使用反射创建对应时也无法保证单例的特性。
解决反序列化的问题需要实现一个接口readResolve
package design.pattern.singleton;
import java.io.Serializable;
/**
* 使用内部类初始化单例,让其形成懒加载
*
* @author SunOlny
*
*/
public class SingletonStartegyInnerClass implements Serializable {
/**
*
*/
private static final long serialVersionUID = 4458426835180723296L;
private SingletonStartegyInnerClass() {
}
private static class Handler {
private static final SingletonStartegyInnerClass singletonStartegyInnerClass = new SingletonStartegyInnerClass();
}
public static SingletonStartegyInnerClass getInstance() {
return Handler.singletonStartegyInnerClass;
}
/**
* 解决反序列化单例问题
*
* @return
*/
public Object readResolve() {
return Handler.singletonStartegyInnerClass;
}
}
要解决反射创建,可以使用枚举天生的单例特性。
package design.pattern.singleton;
/**
* @author SunOlny
*
*/
public enum SingletonStartegyEnum {
instance {
public void execute() {
System.out.println("execute");
}
};
public abstract void execute();
}
package design.pattern.singleton;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import junit.framework.Assert;
import org.junit.Test;
/**
* 测试单例
*
* @author SunOlny
*
*/
public class TestSingleton {
/**
* 未实现readResolve接口,反序列化不能保证单例
*
* @throws ClassNotFoundException
*/
@Test
public void testSingletonSerializableUnReadResolve() throws ClassNotFoundException {
try {
SingletonStrategyStaticAttribute a = SingletonStrategyStaticAttribute.getInstance();
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(a);
ByteArrayInputStream bip = new ByteArrayInputStream(bos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bip);
SingletonStrategyStaticAttribute b = (SingletonStrategyStaticAttribute) ois.readObject();
System.out.println(a == b);
Assert.assertEquals(false, a == b);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 实现了readResolve接口,反序列化能保证单例
*
* @throws ClassNotFoundException
*/
@Test
public void testSingletonSerializableReadResolve() throws ClassNotFoundException {
try {
SingletonStartegyInnerClass a = SingletonStartegyInnerClass.getInstance();
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(a);
ByteArrayInputStream bip = new ByteArrayInputStream(bos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bip);
SingletonStartegyInnerClass b = (SingletonStartegyInnerClass) ois.readObject();
System.out.println(a == b);
Assert.assertEquals(true, a == b);
} catch (IOException e) {
e.printStackTrace();
}
}
}
执行结果
true
false
- singleton单例实现
- 实现Singleton(单例)模式.
- java实现单例 singleton
- 更好的单例(Singleton)实现方式
- 单例模式Singleton的实现
- Iphone 实现Singleton(单例)模式
- 单例模式(Singleton)--Java实现
- Objective C 实现Singleton(单例)模式.
- Python Singleton(单例模式)实现
- iOS singleton单例模式的实现
- C++ Singleton (单例) 模式最优实现
- Python Singleton(单例模式)实现
- C++ Singleton (单例) 模式最优实现
- singleton模式 (单例模式C++实现)
- C++ Singleton (单例) 模式最优实现
- C++ Singleton (单例) 模式最优实现
- java单例(singleton)的实现
- C++ Singleton (单例) 模式最优实现
- ant 使用指南
- python代码调试技巧:pdb,pycharm, pydev, 日志
- margin: 0 auto; 元素水平居中布局无效
- Android学习系列(31)--App自动化之使用Ant编译项目多渠道打包
- 归并排序详解——思路分析以及核心代码(java)实现...非递归实现
- singleton单例实现
- apache commons io 概述(2016-04-21更新)
- 支持左右侧滑的Drawerlayout及使用基类让Drawerlayout在不同Activity中的显示
- 用Jenkins搭建Android自动打包环境
- Android Material Design新UI控件使用大全 二
- LeetCode 321. Create Maximum Number(寻找最大数)
- 使用Jenkins自动化构建Android和iOS应用
- Java,Android,窥探组合的用法。AndroidUI组合设计模式,Java组合设计模式
- centos 7下搭建wiki系统