本文目录一览:
- 1、java 单例模式
- 2、Java单例模式是什么意思?
- 3、在Java中,单例设计模式是什么意思?有什么优势?
- 4、在java开发中,为什么要使用单例模式?
- 5、Java模式设计之单例模式(二)
- 6、JAVA单例模式有哪些?
java 单例模式
System.out.println (Singleton.getInstance());
System.out.println (Singleton.getInstance());
main 函数中有这两句,一摸一样。
第一句执行的时候,第一次调用getInstance(),意思是要获取Singleton的一个对象实例。
而正常情况下,我们要获取对象的话是用 new Singleton(),这个方法的,但是这个方法在Singleton里面被声明为:private ,意思是外界不能调用。
不能调用,我怎么用你的对象?
Singleton里面实现了生成对象的方法,getInstance(),你要用他的对象就必须调用这个方法。
而这个方法里面你也看到了,如果
if(instance == null){
instance = new Singleton();
}
如果没有实例则创建一个新的,但是已经创建过的话,就返回已经存在的实例。
所以输出结果:
net.chelson.chapter5.Singleton@de6ced
net.chelson.chapter5.Singleton@de6ced
你两次调用的这个对象的内存地址都是相同的,也就是说,是同一个东西(对象)
这个总的来说就是:
类的构造方法私有化(防止外界构造新对象)
提供获取实例的方法(用于外界调用)
作用:用于提供只能有一个实例的对象。
Java单例模式是什么意思?
Java单例模式是确保某个类只有一个实例,而且自行实例化并向整个系统提供这个实例,在计算机系统中,线程池、缓存、日志对象、对话框、打印机、显卡的驱动程序对象常被设计成单例的模式;
Java单例模式分三种:懒汉式单例、饿汉式单例、登记式单例。
(1)Java单例模式有以下特点:单例类只能有一个实例;单例类必须自己创建自己的唯一实例;单例类必须给所有其他对象提供这一实例。
(2)Java单例模式的应用范围:每台计算机可以有若干个打印机,但只能有一个Printer Spooler,以避免两个打印作业同时输出到打印机中,每台计算机可以有若干通信端口,系统应当集中管理这些通信端口,以避免一个通信端口同时被两个请求同时调用。
在Java中,单例设计模式是什么意思?有什么优势?
单例模式:保证一个类在使用过程中,只有一个实例。
优势就是单例模式的作用,这个类永远只有一个实例。
还在于可以节省内存,因为它限制了实例的个数,有利于Java垃圾回收。
java的学习建议:
首先要看书读理论,不一定都懂,因为有一个懂的过程;
然后就是分析代码,看看书上的代码的意思,逐行逐行地看,去体会;
最重要的一点就是敲写代码,刚开始不会没关系,照着书一行一行的敲,然后运行,观察结果,把程序运行结果联系程序代码,学得多一点了就尝试修改代码,改一点点看运行结果有什么变化,便于理解程序内部执行的机制。
在java开发中,为什么要使用单例模式?
java单例模式确保一个类只有一个实例,自行提供这个实例并向整个系统提供这个实例。\x0d\x0a特点:\x0d\x0a1,一个类只能有一个实例;\x0d\x0a2,自己创建这个实例;\x0d\x0a3,整个系统都要使用这个实例。\x0d\x0a--------------------------------\x0d\x0aSingleton模式主要作用是保证在Java应用程序中,一个类Class只有一个实例存在。在很多操作中,比如建立目录 数据库连接都需要这样的单线程操作。一些资源管理器常常设计成单例模式。\x0d\x0a外部资源:譬如每台计算机可以有若干个打印机,但只能有一个Printer Spooler,以避免两个打印作业同时输出到打印机中。每台计算机可以有若干个通信端口,系统应当集中管理这些通信端口,以避免一个通信端口被两个请求同时调用。\x0d\x0a内部资源,譬如,大多数的软件都有一个(甚至多个)属性文件存放系统配置。这样的系统应当由一个对象来管理这些属性文件。\x0d\x0a--------------------------------\x0d\x0a单例模式,能避免实例重复创建;\x0d\x0a单例模式,应用于避免存在多个实例引起程序逻辑错误的场合;\x0d\x0a单例模式,较节约内存。
Java模式设计之单例模式(二)
在什么情况下使用单例模式
使用单例模式的条件
使用单例模式有一个很重要的必要条件
在一个系统要求一个类只有一个实例时才应当使用单例模式 反过来说 如果一个类可以有几个实例共存 那么就没有必要使用单例类 但是有经验的读者可能会看到很多不当地使用单例模式的例子 可见做到上面这一点并不容易 下面就是一些这样的情况
例子一
问 我的一个系统需要一些 全程 变量 学习了单例模式后 我发现可以使用一个单例类盛放所有的 全程 变量 请问这样做对吗?
答 这样做是违背单例模式的用意的 单例模式只应当在有真正的 单一实例 的需求时才可使用
一个设计得当的系统不应当有所谓的 全程 变量 这些变量应当放到它们所描述的实体所对应的类中去 将这些变量从它们所描述的实体类中抽出来 放到一个不相干的单例类中去 会使得这些变量产生错误的依赖关系和耦合关系
例子二
问 我的一个系统需要管理与数据库的连接 学习了单例模式后 我发现可以使用一个单例类包装一个Connection 对象 并在finalize()方法中关闭这个Connection 对象 这样的话 在这个单例类的实例没有被人引用时 这个finalize() 对象就会被调用 因此 Connection 对象就会被释放 这多妙啊
答 这样做是不恰当的 除非有单一实例的需求 不然不要使用单例模式 在这里Connection 对象可以同时有几个实例共存 不需要是单一实例
单例模式有很多的错误使用案例都与此例子相似 它们都是试图使用单例模式管理共享资源的生命周期 这是不恰当的
单例类的状态
有状态的单例类
一个单例类可以是有状态的(stateful) 一个有状态的单例对象一般也是可变(mutable) 单例对象
有状态的可变的单例对象常常当做状态库(repositary)使用 比如一个单例对象可以持有一个int 类型的属性 用来给一个系统提供一个数值惟一的序列号码 作为某个贩卖系统的账单号码 当然 一个单例类可以持有一个聚集 从而允许存储多个状态
没有状态的单例类
另一方面 单例类也可以是没有状态的(stateless) 仅用做提供工具性函数的对象 既然是为了提供工具性函数 也就没有必要创建多个实例 因此使用单例模式很合适 一个没有状态的单例类也就是不变(Immutable) 单例类 关于不变模式 读者可以参见本书的 不变(Immutable )模式 一章
多个JVM 系统的分散式系统
EJB 容器有能力将一个EJB 的实例跨过几个JVM 调用 由于单例对象不是EJB 因此 单例类局限于某一个JVM 中 换言之 如果EJB 在跨过JVM 后仍然需要引用同一个单例类的话 这个单例类就会在数个JVM 中被实例化 造成多个单例对象的实例出现 一个J EE应用系统可能分布在数个JVM 中 这时候不一定需要EJB 就能造成多个单例类的实例出现在不同JVM 中的情况
如果这个单例类是没有状态的 那么就没有问题 因为没有状态的对象是没有区别的 但是如果这个单例类是有状态的 那么问题就来了 举例来说 如果一个单例对象可以持有一个int 类型的属性 用来给一个系统提供一个数值惟一的序列号码 作为某个贩卖系统的账单号码的话 用户会看到同一个号码出现好几次
在任何使用了EJB RMI 和JINI 技术的分散式系统中 应当避免使用有状态的单例模式
多个类加载器
同一个JVM 中会有多个类加载器 当两个类加载器同时加载同一个类时 会出现两个实例 在很多J EE 服务器允许同一个服务器内有几个Servlet 引擎时 每一个引擎都有独立的类加载器 经有不同的类加载器加载的对象之间是绝缘的
lishixinzhi/Article/program/Java/gj/201311/27644
JAVA单例模式有哪些?
一、懒汉式单例\x0d\x0a在类加载的时候不创建单例实例。只有在第一次请求实例的时候的时候创建,并且只在第一次创建后,以后不再创建该类的实例。\x0d\x0a \x0d\x0apublic class LazySingleton {\x0d\x0a /**\x0d\x0a * 私有静态对象,加载时候不做初始化\x0d\x0a */\x0d\x0a private static LazySingleton m_intance=null;\x0d\x0a /**\x0d\x0a * 私有构造方法,避免外部创建实例\x0d\x0a */\x0d\x0a private LazySingleton(){\x0d\x0a }\x0d\x0a /**\x0d\x0a * 静态工厂方法,返回此类的唯一实例. \x0d\x0a * 当发现实例没有初始化的时候,才初始化.\x0d\x0a */\x0d\x0a synchronized public static LazySingleton getInstance(){\x0d\x0a if(m_intance==null){\x0d\x0a m_intance=new LazySingleton();\x0d\x0a }\x0d\x0a return m_intance;\x0d\x0a }\x0d\x0a}\x0d\x0a\x0d\x0a二、饿汉式单例\x0d\x0a在类被加载的时候,唯一实例已经被创建。\x0d\x0a \x0d\x0apublic class EagerSingleton {\x0d\x0a /**\x0d\x0a * 私有的(private)唯一(static final)实例成员,在类加载的时候就创建好了单例对象\x0d\x0a */\x0d\x0a private static final EagerSingleton m_instance = new EagerSingleton();\x0d\x0a /**\x0d\x0a * 私有构造方法,避免外部创建实例\x0d\x0a */\x0d\x0a private EagerSingleton() {\x0d\x0a }\x0d\x0a /**\x0d\x0a * 静态工厂方法,返回此类的唯一实例.\x0d\x0a * @return EagerSingleton\x0d\x0a */\x0d\x0a public static EagerSingleton getInstance() {\x0d\x0a return m_instance;\x0d\x0a }\x0d\x0a}\x0d\x0a \x0d\x0a************************************************************************************** 懒汉方式,指全局的单例实例在第一次被使用时构建; \x0d\x0a饿汉方式,指全局的单例实例在类装载时构建 \x0d\x0a**************************************************************************************\x0d\x0a\x0d\x0a三、登记式单例\x0d\x0a这个单例实际上维护的是一组单例类的实例,将这些实例存放在一个Map(登记薄)中,对于已经登记过的实例,则从工厂直接返回,对于没有登记的,则先登记,而后返回。\x0d\x0apublic class RegSingleton {\x0d\x0a /**\x0d\x0a * 登记薄,用来存放所有登记的实例\x0d\x0a */\x0d\x0a private static Map m_registry = new HashMap();\x0d\x0a //在类加载的时候添加一个实例到登记薄\x0d\x0a static {\x0d\x0a RegSingleton x = new RegSingleton();\x0d\x0a m_registry.put(x.getClass().getName(), x);\x0d\x0a }\x0d\x0a /**\x0d\x0a * 受保护的默认构造方法\x0d\x0a */\x0d\x0a protected RegSingleton() {\x0d\x0a }\x0d\x0a /**\x0d\x0a * 静态工厂方法,返回指定登记对象的唯一实例;\x0d\x0a * 对于已登记的直接取出返回,对于还未登记的,先登记,然后取出返回\x0d\x0a * @param name\x0d\x0a * @return RegSingleton\x0d\x0a */\x0d\x0a public static RegSingleton getInstance(String name) {\x0d\x0a if (name == null) {\x0d\x0a name = "RegSingleton";\x0d\x0a }\x0d\x0a if (m_registry.get(name) == null) {\x0d\x0a try {\x0d\x0a m_registry.put(name, (RegSingleton) Class.forName(name).newInstance());\x0d\x0a } catch (InstantiationException e) {\x0d\x0a e.printStackTrace();\x0d\x0a } catch (IllegalAccessException e) {\x0d\x0a e.printStackTrace();\x0d\x0a } catch (ClassNotFoundException e) {\x0d\x0a e.printStackTrace();\x0d\x0a }\x0d\x0a }\x0d\x0a return m_registry.get(name);\x0d\x0a }\x0d\x0a /**\x0d\x0a * 一个示意性的商业方法\x0d\x0a * @return String\x0d\x0a */\x0d\x0a public String about() {\x0d\x0a return "Hello,I am RegSingleton!";\x0d\x0a }\x0d\x0a}