您的位置:首页 > 其它

单例设计模式

2016-01-04 21:55 274 查看




















单例设计模式代码:

/**
* 饿汉式
* @author zhangjianbin
*
*/
public class Demo1 {
//类初始化时,立即加载对象(如果后面没有调用这个类,而加载这个对象又比较耗时,
//则白干了,并且是天然的线程安全的)
private static final Demo1 s = new Demo1();
private Demo1() {
}

//不需要同步,所以调用效率高
public static Demo1 instance() {
return s;
}
}


/**
* 懒汉式
* @author zhangjianbin
*
*/
public class Demo1 {
private static  Demo1 s = null;
private Demo1() {
}
public static synchronized Demo1 instance() {
if(s == null){
s = new Demo1();
}
return s;
}
}


/**
* 静态内部类实现单例
*
* @author zhangjianbin
*
*/
public class Demo3 {
private Demo3() {
}

private static class InnerClass {
private static final Demo3 sc = new Demo3();
}

public static Demo3 getInstance() {
return InnerClass.sc;
}

}


/**
* 枚举实现单例
*
* @author zhangjianbin
*
*/
public enum Demo4 {
instance;//本身就是一种单例的,线程安全的
}


单例设计模式反射和对象序列化破解:

//反射破解单例
public static void main(String[] args) throws Exception {

// 获取类
Class<Demo1> forName = (Class<Demo1>) Class.forName("com.zhang.singleton.Demo1");
// 获取类的构造器
Constructor<Demo1> declaredConstructor = forName.getDeclaredConstructor(null);
// 暴力破解,访问私有属性
declaredConstructor.setAccessible(true);

// 利用构造器创建对象
Object newInstance = declaredConstructor.newInstance(null);
Object newObject2 = declaredConstructor.newInstance(null);

System.err.println(newInstance == newObject2); //false

}


public static void main(String[] args) throws Exception {

Demo1 d1 = Demo1.instance();
Demo1 d2 = Demo1.instance();

//对象序列化
FileOutputStream fos = new FileOutputStream(new File("d:/a.txt"));
ObjectOutputStream os =  new ObjectOutputStream(fos);
os.writeObject(d1);
os.close();
fos.close();

//对象反序列化
FileInputStream fs = new FileInputStream(new File("d:/a.txt"));
ObjectInputStream in = new ObjectInputStream(fs);
Object readObject = in.readObject();
System.err.println(d1 == readObject); //false

}
//阻止反序列化破解(在对象类中添加即可)
private Object readResolve(){
return s;
}


//多线程测试单例模式不同实现的执行效率
public static void main(String[] args) throws Exception {
long start = System.currentTimeMillis();
int threadNum = 10;
final CountDownLatch count = new CountDownLatch(threadNum); //有10个线程
for (int i = 0; i < threadNum; i++) {
new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i <10000; i++) {
Demo3 d  = Demo3.getInstance();
}
count.countDown();//每个线程执行完毕后,计数器减1
}
}).start();
}

count.await();//等待全部线程执行完毕后,才向下执行
long end = System.currentTimeMillis();
System.err.println(end- start);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: