1.饿汉式

public class SingletonDemo {
private static SingletonDemo s=new SingletonDemo();
private SingletonDemo() {}
public static SingletonDemo getInstance() {
return s;
}
}
public class Test {
public static void main(String[] args) {
SingletonDemo s=SingletonDemo.getInstance();
}
}

步骤:    1.new出静态对象

    2.构造方法私有化

    3.写一个方法返回静态对象

说明:   1.由于加载类时天然的是线程安全

    2.方法没有同步,调用效率高

    3.立即加载,没有延时加载的优势

2.懒汉式(延时加载)

public class SingletonDemo {
private static SingletonDemo s;
private SingletonDemo() {}
public static synchronized SingletonDemo getInstance() {
if(s==null) s=new SingletonDemo();
return s;
}
}
public class Test {
public static void main(String[] args) {
SingletonDemo s=SingletonDemo.getInstance();
}
}

优势:   1.修改点同步,在线程高并发时,能够保证安全性

    2.延时new出类,能够做到用的时候去new它

3.双重检测锁实现

由于java编译器优化的原因和JVM底层内部模型的原因,偶尔会出一点问题,不建议使用

这个模式将同步内容下方到if内部,提高了执行效率,不必每次获取对象时都进行同步,至于一次才同步

public class SingletonDemo {
private static SingletonDemo instance;
private SingletonDemo() {}
public static SingletonDemo getInstance() {
if(instance==null) {
SiSingletonDemo sc;
synchronized (SingletonDemo.class) {
sc=instance;
}
if(sc==null) {
synchronized (SingletonDemo.class) {
if(sc==null) {
sc=new SingletonDemo();
}
}
instance=sc;
}
}
return instance;
}
}

4.静态内部类(懒加载)

public class SingletonDemo {
private static class SingletonClassInstance{
private static final SingletonDemo instance=new SingletonDemo();
}
private SingletonDemo() {}
public static SingletonDemo getInstance() {
return SingletonDemo.getInstance();
}
}

5.枚举单例模式

public enum SingletonDemo {
INSTANCE; //枚举本来就是单例对象
//避免了反序列和反射的调用
//缺点,没有延时调用
public void singletonOperation() { }
}

6.统一建模语言UML(unified modeling language)

可以拖动类做uml图

利用反射破解单例设计模式(不包含枚举单例,因为枚举型单例是利用JVM底层实现的单例设计模式)

public class TestSingleObject {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
SingleObject s1=SingleObject.getInstance();
SingleObject s2=SingleObject.getInstance(); Class<SingleObject> clazz=(Class<SingleObject>) Class.forName("com.littlepage.singletonPattern.SingleObject");
Constructor<SingleObject> c=clazz.getDeclaredConstructor(null);
c.setAccessible(true);//跳过检测
SingleObject s3=c.newInstance();
SingleObject s4=c.newInstance();
System.out.println(s1);
System.out.println(s2);
System.out.println(s3);
System.out.println(s4);
}
}

解决方法,在空参构造中加入

if(SingletonObject!=null){

throw new runtimeExpection();

}

进行调用时抛出异常就行

//举例
public class SingleObject {
public static class SingleObjectInstance{
public static final SingleObject instance=new SingleObject();
}
private SingleObject(){
if(SingleObjectInstance.instance!=null){
try {
throw new Exception("运行时异常"); } catch (Exception e) {
e.printStackTrace();
System.exit();
}
}
}
public static SingleObject getInstance(){
return SingleObjectInstance.instance;
}
}

利用序列化反序列化进行破解

public class TestSingleObject {
public static void main(String[] args) throws IOException, ClassNotFoundException {
SingleObject s1=SingleObject.getInstance();
System.out.println(s1);
FileOutputStream fops=new FileOutputStream("d:/a.txt");
ObjectOutputStream oops=new ObjectOutputStream(fops);
oops.writeObject(s1);
oops.close(); ObjectInputStream ois =new ObjectInputStream(new FileInputStream("d:/a.txt"));
SingleObject s2=(SingleObject) ois.readObject();
System.out.println(s2);
ois.close(); }
}

解决办法:

private Object resdResolve() throws ObjectStreamException{
return SingleObjectInstance.instance;
}

添加该代码,可以使读取Object时直接返回已经存在的实例

设计模式(三)Singleton Pattern单例设计模式的更多相关文章

  1. Java面试 - 什么是单例设计模式,为什么要使用单例设计模式,如何实现单例设计模式(饿汉式和懒汉式)?

    什么是单例设计模式? 单例设计模式就是一种控制实例化对象个数的设计模式. 为什么要使用单例设计模式? 使用单例设计模式可以节省内存空间,提高性能.因为很多情况下,有些类是不需要重复产生对象的. 如果重 ...

  2. 【工作中学习1】两个设计模式:Singleton(单例)和 Adapter(适配器)

    好久没有写自己的学习小博客,罪过罪过..最近本菜鸟在项目中接触到经常用到的设计模式,首先是Singleton(单例),这个相信大家都会用到很多,所以自己用代码实现一下,有助于自己学习理解,如有不对,请 ...

  3. GOF设计模式之1:单例设计模式

    1.单例设计模式核心作用: 保证一个类只有一个实例,并且提供了访问该实例的全局访问点 2.常见应用场景: window的任务管理器 项目中读取配置文件一般也是一个单例模式 数据库连接池的设计也是采用单 ...

  4. IOS设计模式第二篇之单例设计模式

    现在我们的组件已经有组织了.你需要从其他的地方得到数据,你也可以创建一个API类管理数据这个下个设计模式单例里面介绍. 这个单例设计模式确保这个类仅仅拥有一个实例,并且为这个实例提供一个全局的访问点. ...

  5. 初学者学Java设计模式(一)------单例设计模式

    单例设计模式 单例设计模式是指一个类只会生成一个对象,优点是他可以确保所有对象都访问唯一实例. 具体实现代码如下: public class A { public static void main(S ...

  6. 【设计模式】Java之单例设计模式

    1.单例设计模式:一个类只能有一个对象 1.1 创建单例类的步骤: 1.将构造方法私有化 2.创建私有的静态成员变量 3.共有的静态成员方法,提供当前的唯一对象 1.1 创建单例的两种方式: 1.饿汉 ...

  7. Java Notes 00 - Singleton Pattern(单例总结)

    转:http://hukai.me/java-notes-singleton-pattern/ 这里不赘述单例模式的概念了,直接演示几种不同的实现方式. 0)Eager initialization ...

  8. 设计模式课程 设计模式精讲 8-10 单例设计模式-ThreadLocal线程单例

    1 课程讲解 1.1 应用场景 2 代码演练 2.1 threadLocal应用 1 课程讲解 1.1 应用场景 多线程的时候: 使用同步锁使用时间换空间的方式,(线程排队时间比较长) 而使用thre ...

  9. 设计模式课程 设计模式精讲 8-8 单例设计模式-Enum枚举单例、原理源码解析以及反编译实战

    1 课堂解析 2 代码演练 2.1 枚举类单例解决序列化破坏demo 2.2 枚举类单例解决序列化破坏原理 2.3 枚举类单例解决反射攻击demo 2.4 枚举类单例解决反射攻击原理 3 jad的使用 ...

随机推荐

  1. 数据库-MySQL入门

    什么是数据库? 一定方式储存在一起.能与多个用户共享.具有尽可能小的冗余度.与应用程序彼此独立的数据集合 数据库管理系统(简称DBMS):是为管理数据库而设计的电脑软件系统,一般具有存储.截取.安全保 ...

  2. winform跨线程访问控件

    首先说下,.net 2.0以后加强了安全机制,不允许在winform中直接跨线程访问控件的属性.所以除了控件所在的线程外的线程调用会抛异常 (Cross-thread operation not va ...

  3. lucene 全文检索工具的介绍

    Lucene:全文检索工具:这是一种思想,使用的是C语言写出来的 1.Lucene就是apache下的一个全文检索工具,一堆的jar包,我们可以使用lucene做一个谷歌和百度一样的搜索引擎系统 2. ...

  4. Linux内核Socket参数调优

    可调优的内核变量存在两种主要接口:sysctl命令和/proc文件系统,proc中与进程无关的所有信息都被移植到sysfs中.IPV4协议栈的sysctl参数主要是sysctl.net.core.sy ...

  5. Codeforces 235C Cyclical Quest - 后缀自动机

    Some days ago, WJMZBMR learned how to answer the query "how many times does a string x occur in ...

  6. docker 给运行的容器映射本地端口

    1.提交运行中的容器为一个镜像   (这样不会丢失在容器的各种操作) docker commit  tang     tang1 ###  tang(运行容器名称)   tang1(生成镜像名称) 2 ...

  7. 一、数据库表中字段的增删改查,二、路由基础.三、有名无名分组.四、多app共存的路由分配.五、多app共存时模板冲突问题.六、创建app流程.七、路由分发.八、路由别名,九、名称空间.十、反向解析.十一、2.x新特性.十二、自定义转换器

    一.数据库表中字段的增删改查 ''' 直接在modules中对字段进行增删改查 然后在tools下点击Run manage.py Task执行makemigrations和migrate 注意在执行字 ...

  8. RAC +MVVM

    https://blog.csdn.net/capf_sam/article/details/60960530 https://blog.csdn.net/capf_Sam/article/detai ...

  9. ODAC(V9.5.15) 学习笔记(三)TOraSession(4)

    4. 数据库信息 名称 类型 说明 GetDatabaseNames 获取对应的数据库对象名称列表 GetSequenceNames GetStoredProcNames GetTableNames ...

  10. 深入了解JVW

    Java内存组成介绍:堆(Heap)和非堆(Non-heap)内存 按照官方的说法:“Java 虚拟机具有一个堆,堆是运行时数据区域,所有类实例和数组的内存均从此处分配.堆是在 Java 虚拟机启动时 ...