synchronized 异常信息存在哪里 单例模式有几种?如何优化?
单例模式有几种?如何优化?
在某些系统中,为了节省内存资源和保证数据内容的一致性,对于某些类只能创建一个实例,这种模式称为singleton模式。
单体模式的定义和特征
Singleton模式的定义:指一个类只有一个实例,并且该类可以自己创建这个实例的模式。比如在Windows中只能打开一个任务管理器,可以避免打开多个任务管理器窗口造成的内存资源浪费,或者每个窗口显示内容不一致。
在计算机系统中,还有Windows的回收站,操作系统中的文件系统,多线程中的线程池,显卡的驱动对象,打印机的后台处理服务,应用程序的日志对象,数据库的连接池,网站的计数器,Web应用程序的配置对象,应用程序中的对话框,系统中的缓存,这些往往被设计成单一的案例。
Singleton模式在现实生活中也有广泛应用,比如公司CEO、部门经理等。J2EE标准中的ServletContext和ServletContextConfig,Spring框架应用中的ApplicationContext和数据库中的连接池也是singleton模式。
单例模式有三个特征:
单例类只有一个实例对象;singleton对象必须由singleton类本身创建;singleton类为访问singleton提供了一个全局访问点。单例模式的优点和缺点。
单例模式的优势:
Singleton模式可以保证内存中只有一个实例,减少了内存开销。可以避免多次占用资源。Singleton模式设置了全局访问点,可以优化和共享对资源的访问。单一模式和。;的缺点:
Singleton模式一般没有接口,所以很难扩展。如果要扩展,除了修改原代码,没有第二条路,这违背了开放封闭原则。在并发测试中,单件模式不利于代码调试。在调试期间,如果singleton中的代码没有完成,就不能模拟新的对象。单一模式和。;的功能代码通常写在一个类中。如果功能设计不合理,很容易违反单一责任原则。Singleton模式看起来很简单,实现起来也很简单。单体模式是面试中的一个高频面试问题。希望大家好好学习,掌握独生子女模式,提升核心竞争力,给面试加分,顺利拿到Offer。
单一模式和。;的应用场景
对于Java,singleton模式可以保证在一个JVM中只有一个实例。单一模式和。;的应用场景主要包括以下几个方面。
对于一些需要经常创建的类,使用单例可以减轻系统的内存压力,减少GC。当一个类只需要生成一个对象时,比如一个类的班长,每个人 s身份证号等。有些类在创建实例时会占用更多的资源,或者实例化需要很长时间,并且经常被使用。当一个类需要频繁实例化,并且创建的对象被频繁销毁时,比如多线程线程池、网络连接池等。频繁访问数据库或文件的对象。对于一些控制硬件层面的操作,或者从系统角度看应该是单个控制逻辑的操作,如果有多个实例,系统就完全乱套了。当需要共享对象时。因为在单例模式中只能创建一个对象,所以共享这个对象可以节省内存并加快对象访问。如Web中的配置对象、数据库的连接池等。singleton模式的结构与实现
单一模式是最简单的设计模式之一。通常,普通类的构造函数是公共的,外部类可以通过 "新构造函数() "。但是,如果将类的构造函数设置为private,则外部类无法调用该构造函数,因此无法生成多个实例。此时,类本身必须定义一个静态私有实例,并提供一个静态公共函数来创建或获取静态私有实例。
让 分析了它的基本结构和实现方法。
1.单例模式的结构
单一模式和。;的主要角色如下。
Singleton类:包含一个实例并且可以自己创建这个实例的类。访问类:使用单例的类。其结构如图1所示。
图1单例模式的结构图。
2.单例模式的实现
单例模式通常有两种实现形式。
第一种:懒惰的单一案例
这种模式的特点是类加载时不生成singleton,只有第一次调用getlnstance方法时才创建。代码如下:
公共类LazySingleton {
private static volatile lazy singleton实例null//确保实例在所有线程中同步。
列兵LazySingleton() {
} //private防止类被外部实例化。
公共静态同步LazySingleton getInstance() {
//在//getInstance方法之前同步
if(实例为空){
实例new LazySingleton()
}
返回实例
}
}
注意:如果你正在写一个多线程程序,不要 不要删除前面代码中的关键字volatile和synchronized,否则会有线程不安全的问题。如果你不 t删除这两个关键字,可以保证线程安全,但是每次访问都要同步,会影响性能,消耗更多资源。这就是懒单胞的缺点。第二种:饿汉式单例
这种模式的特点是,一旦加载了类,就会创建一个singleton,这确保了在调用getInstance方法之前该singleton已经存在。
公共类饥饿Singleton {
私有静态最终HungrySingleton实例new HungrySingleton()
二等兵HungrySingleton() {
}
公共静态HungrySingleton getInstance() {
返回实例
}
}
饿了么中文singleton在创建类的同时创建了一个静态对象供系统使用,以后也不会更改,所以是线程安全的,可以直接用于多线程,没有问题。
单例模式的应用实例
【例1】使用lazy singleton模式模拟生成美国当前总统对象。
分析:每届美国只有一位总统,所以这个例子适合用singleton模式来实现。图2是lazy singleton实现的结构图。
图2美国总统发电机结构图
程序代码如下:
公共类SingletonLazy {
公共静态void main(String[] args) {
zt1总裁()
()//输出总统的名字。
zt2总统()
()//输出总统的名字。
if (zt1 zt2) {
他们是同一个人!)
}否则{
(他们不是同一个人!)
}
}
}
班长{
私有静态易变总统实例null//确保实例在所有线程中同步。
//private防止类被外部实例化。
私人总裁(){
(产生一个总统!)
}
公共静态同步总统getInstance() {
//向getInstance方法添加同步。
if(实例为空){
实例新总裁()
}否则{
已经有总统了,新总统无法产生!)
}
返回实例
}
public void getName() {
(我是美国总统:特朗普。)}
}
程序运行结果如下:
产生一个总统!
我是美国总统:特朗普。
已经有总统了,新总统无法产生!
我是美国总统:特朗普。
他们是同一个人!
【例2】用饿汉风格的单体模式模拟生成猪八戒对象。
分析:和前面的例子类似,只有一个猪八戒,所以这个例子也适合用singleton模式实现,所以使用了框架形式的JFrame组件。这里的猪八戒类是一个singleton类,可以定义为panel JPanel的子类,包含了保存猪八戒图片的标签,客户端表单可以获取猪八戒对象并显示。图3是饿了么汉单例实现的结构图。
图3猪八戒发电机结构图
程序代码如下:
导入*
导入javax.swing.*
公共类单身者{
公共静态void main(String[] args) {
JFrame jf新JFrame(饥饿单例模式测试)
(新网格布局(1,2))
容器内容窗格()
八戒obj1()
(obj1)
八戒obj2()
(obj2)
if (obj1 obj2) {
他们是同一个人!)
}否则{
(他们不是同一个人!)
}
()
(正确)
(JFrame。出口_开_关)
}
}
Bajie类扩展JPanel {
私有静态Bajie实例new Bajie()
大兵八戒(){
JLabel l1新JLabel(新图像图标())
(l1)
}
公共静态Bajie getInstance() {
返回实例
}
}
程序的运行结果如图4所示。
图4猪八戒发电机运行结果
单例模式的扩展
Singleton模式可以扩展为有限的multi-TCM模式,可以生成有限数量的实例并保存在ArrayList中,客户需要时可以随机获取。其结构图如图5所示。
图5有限多实例模式的结构图
Spring如何解决循环依赖的问题?
你的问题太大了,很难解释清楚。简单来说,Spring执行InstantiateBean中的构造器方法来构造一个实例。如果它是单例的,它将将其放入singletonBeanFactory的缓存中,然后执行populateBean方法来设置属性。循环依赖的问题通过singletonBeanFactory的缓存来解决。推荐你看看这个链接。作者讲得非常仔细清晰。
版权声明:本文内容由互联网用户自发贡献,本站不承担相关法律责任.如有侵权/违法内容,本站将立刻删除。