你用杯子喝可乐,喝完了不刷,继续去倒果汁喝,就是单例。
你用杯子喝可乐,直接扔了杯子,换个杯子去倒果汁喝,就是多例。
数据库连接池就是单例模式,有且仅有一个连接池管理者,管理多个连接池对象。
1. 什么是单例多例:
所谓单例就是所有的请求都用一个对象来处理,比如我们常用的service和dao层的对象通常都是单例的,而多例则指每个请求用一个新的对象来处理,比如action;
2. 如何产生单例多例:
在通用的SSH中,单例在spring中是默认的,如果要产生多例,则在配置文件的bean中添加scope="prototype";
3. 为什么用单例多例:
之所以用单例,是因为没必要每个请求都新建一个对象,这样子既浪费CPU又浪费内存;
之所以用多例,是为了防止并发问题;即一个请求改变了对象的状态,此时对象又处理另一个请求,而之前请求对对象状态的改变导致了对象对另一个请求做了错误的处理;
用单例和多例的标准只有一个:
当对象含有可改变的状态时(更精确的说就是在实际应用中该状态会改变),则多例,否则单例;
单例其实就在内存中该对象只有一个内存对应地址。无论你多少个线程访问那个对象,都是同一个地址。这样节省内存
4. 何时用单例?何时用多例?
对于struts2来说,action必须用多例,因为action本身含有请求参数的值,即可改变的状态;
而对于struts1来说,action则可用单例,因为请求参数的值是放在actionForm中,而非action中的;
另外要说一下,并不是说service或dao一定是单例,标准同第3点所讲的,就曾见过有的service中也包含了可改变的状态,同时执行方法也依赖该状态,但一样用的单例,这样就会出现隐藏的BUG,而并发的BUG通常很难重现和查找;
单例模式
懒汉单例
饿汉式
登记式单例
java中单例模式是一种常见的设计模式,单例模式的写法有好几种,这里主要介绍三种:懒汉式单例、饿汉式单例、登记式单例。
单例模式有以下特点:
1、单例类只能有一个实例。
2、单例类必须自己创建自己的唯一实例。
3、单例类必须给所有其他对象提供这一实例。
单例模式确保某个类只有一个实例,而且自行实例化并向整个系统提供这个实例。在计算机系统中,线程池、缓存、日志对象、对话框、打印机、显卡的驱动程序对象常被设计成单例。这些应用都或多或少具有资源管理器的功能。每台计算机可以有若干个打印机,但只能有一个Printer Spooler,以避免两个打印作业同时输出到打印机中。每台计算机可以有若干通信端口,系统应当集中管理这些通信端口,以避免一个通信端口同时被两个请求同时调用。总之,选择单例模式就是为了避免不一致状态,避免政出多头。
饿汉式和懒汉式区别
从名字上来说,饿汉和懒汉,
饿汉就是类一旦加载,就把单例初始化完成,保证getInstance的时候,单例是已经存在的了,
而懒汉比较懒,只有当调用getInstance的时候,才回去初始化这个单例。
另外从以下两点再区分以下这两种方式:
1、线程安全:
饿汉式天生就是线程安全的,可以直接用于多线程而不会出现问题,
懒汉式本身是非线程安全的,为了实现线程安全有几种写法,分别是上面的1、2、3,这三种实现在资源加载和性能方面有些区别。
2、资源加载和性能:
饿汉式在类创建的同时就实例化一个静态对象出来,不管之后会不会使用这个单例,都会占据一定的内存,但是相应的,在第一次调用时速度也会更快,因为其资源已经初始化完成,
而懒汉式顾名思义,会延迟加载,在第一次使用该单例的时候才会实例化对象出来,第一次调用时要做初始化,如果要做的工作比较多,性能上会有些延迟,之后就和饿汉式一样了。
至于1、2、3这三种实现又有些区别,
第1种,在方法调用上加了同步,虽然线程安全了,但是每次都要同步,会影响性能,毕竟99%的情况下是不需要同步的,
第2种,在getInstance中做了两次null检查,确保了只有第一次调用单例的时候才会做同步,这样也是线程安全的,同时避免了每次都同步的性能损耗
第3种,利用了classloader的机制来保证初始化instance时只有一个线程,所以也是线程安全的,同时没有性能损耗,所以一般我倾向于使用这一种。
什么是线程安全?
如果你的代码所在的进程中有多个线程在同时运行,而这些线程可能会同时运行这段代码。如果每次运行结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的是一样的,就是线程安全的。
或者说:一个类或者程序所提供的接口对于线程来说是原子操作,或者多个线程之间的切换不会导致该接口的执行结果存在二义性,也就是说我们不用考虑同步的问题,那就是线程安全的。
应用
以下是一个单例类使用的例子,以懒汉式为例,这里为了保证线程安全,使用了双重检查锁定的方式:
public class TestSingleton { String name = null; private TestSingleton() { } private static volatile TestSingleton instance = null; public static TestSingleton getInstance() { if (instance == null) { synchronized (TestSingleton.class) { if (singleton == null) { singleton = new TestSingleton(); } } } return instance; } public String getName() { return name; } public void setName(String name) { this.name = name; } public void printInfo() { System.out.println("the name is " + name); } }
可以看到里面加了volatile关键字来声明单例对象,既然synchronized已经起到了多线程下原子性、有序性、可见性的作用,为什么还要加volatile呢,原因已经在下面评论中提到,
还有疑问可参考http://www.iteye.com/topic/652440
和http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html
public class TMain { public static void main(String[] args){ TestStream ts1 = TestSingleton.getInstance(); ts1.setName("jason"); TestStream ts2 = TestSingleton.getInstance(); ts2.setName("0539"); ts1.printInfo(); ts2.printInfo(); if(ts1 == ts2){ System.out.println("创建的是同一个实例"); }else{ System.out.println("创建的不是同一个实例"); } } }
运行结果:
结论:由结果可以得知单例模式为一个面向对象的应用程序提供了对象惟一的访问点,不管它实现何种功能,整个应用程序都会同享一个实例对象。
对于单例模式的几种实现方式,知道饿汉式和懒汉式的区别,线程安全,资源加载的时机,还有懒汉式为了实现线程安全的3种方式的细微差别。
相关推荐
在这个`CloudMusic`项目中,可以预见的是,单例模式可能被用来管理数据库连接,工厂模式用于根据需求创建不同的音乐播放器对象,动态代理可能用于实现用户行为的日志记录或权限控制,而适配器模式则可能用于集成第三...
不错的可用来练手、课程设计、毕业设计的Javaweb项目源码:仓库管理系统 不错的可用来练手、课程设计、毕业设计的Javaweb项目源码:仓库管理系统 不错的可用来练手、课程设计、毕业设计的Javaweb项目源码:仓库管理...
在JavaWeb中,它们作为数据传输对象(DTO)或模型对象(MO)。实例会展示如何编写和使用JavaBean。 7. **Web安全**:实例可能涵盖用户认证与授权,如使用Spring Security实现登录验证和权限控制,以及防止SQL注入和...
Spring MVC是JavaWeb中常用的MVC框架,提供了强大的功能支持。 3. **JDBC与数据库交互**:JavaWeb项目通常需要与数据库进行交互,如MySQL。JDBC(Java Database Connectivity)是Java连接数据库的标准API,通过它,...
总之,JavaWeb项目实训是一个综合性的学习过程,涉及数据库操作、前端开发、文件传输、项目构建等多个方面。通过这样的实践,你可以逐步提升自己的技能,为未来更复杂的Web应用开发打下坚实基础。
1. **Servlet**:Servlet是JavaWeb中的后端处理组件,负责接收和响应HTTP请求。在物流信息网中,Servlet可能会处理用户登录、注册、下单、查询等操作。 2. **JSP文件**:JSP文件通常用于显示数据和用户界面。它们...
本书精选了多个JavaWEB项目案例,每个案例都围绕一个特定的主题展开,涵盖了不同业务场景下的解决方案。下面简要介绍几个典型的案例: 1. **电商网站**:该项目模拟了一个简单的电商平台,包括商品管理、订单处理等...
【标题】"尚硅谷JavaWeb项目微头条代码" 涉及的是一个基于JavaWeb的开发实践,其中可能包括了完整的项目结构和配置文件。这个项目可能是为了教学或实际应用目的,让学生或开发者了解如何使用JavaWeb技术进行实际的...
【JavaWeb项目案例1.zip】是一个包含多个文件的压缩包,主要涉及的是JavaWeb开发的知识点。这个项目可能是一个简单的新闻展示系统或者教学示例,其中包含三个HTML页面(news2.html、news1.html、news0.html)以及一...
在JavaWeb中,Spring MVC是一个常用的MVC框架。 4. **JDBC(Java Database Connectivity)**: JDBC是Java访问数据库的标准API,通过它可以连接到各种数据库,执行SQL语句,处理结果集。在JavaWeb项目中,JDBC用于...
教务管理系统javaweb项目教务管理系统javaweb项目教务管理系统javaweb项目教务管理系统javaweb项目教务管理系统javaweb项目教务管理系统javaweb项目教务管理系统javaweb项目教务管理系统javaweb项目教务管理系统...
java源码 仿360buy京东商城源码 京东JavaWeb项目源代码.zipjava源码 仿360buy京东商城源码 京东JavaWeb项目源代码.zipjava源码 仿360buy京东商城源码 京东JavaWeb项目源代码.zipjava源码 仿360buy京东商城源码 京东...
【JavaWeb项目报告概述】 本项目报告主要针对的是一个名为"爱豆网站"的JavaWeb应用,旨在为追星人群提供一个集新闻、信息、商品展示、用户交流于一体的服务平台。该网站着重解决网络信息混乱、真实性难以辨别等问题...
Spring MVC是JavaWeb中常用的MVC框架,它简化了开发流程,实例中可能会有Spring Boot或Spring MVC的运用,包括控制器定义、模型绑定、视图解析等。 4. **JDBC**:Java Database Connectivity,用于在Java程序中连接...
80个JavaWeb项目(包含项目源码) ExtS2.2开源网络硬盘系统dogdisk.rar WAP图铃下载系统unimg.rar 北雨下裁系统v1.0.1 bydown101.rar 仿163网盘无刷新文件上传for Jsp_fileupload _jsp.rar 宏软JSP上传系统v1.0 ...
总的来说,这个"javaweb项目文件.zip"压缩包代表了一个完整的JavaWeb项目实例,涵盖了Web开发的多个核心概念和技术,包括数据库操作、前端展示、服务器端处理以及框架应用等。通过学习和理解这些知识点,开发者能够...
在JavaWeb开发中,Eclipse是一款非常流行的集成开发环境(IDE),它提供了强大的代码编辑、调试和项目管理功能。本文将详细阐述如何在Eclipse中配置JavaWeb项目的开发环境,以便进行高效、顺利的开发工作。 首先,...
JavaWeb是一种基于Java技术的Web应用开发框架,用于构建动态、交互式的互联网应用程序。...此外,良好的代码组织结构和规范,以及安全性考量(如防止SQL注入、XSS攻击等)也是项目开发中不可或缺的部分。
这个项目涵盖了前端用户界面、后台管理系统以及与数据库的交互等多个核心功能模块,旨在提供一个方便、快捷且直观的订餐体验。 在【需求】部分,我们可以了解到系统应具备的主要功能,例如用户注册与登录、浏览菜单...
2. **MVC架构**:在JavaWeb中,Model-View-Controller(MVC)架构是常见的设计模式。模型(Model)处理业务逻辑,视图(View)负责展示数据,控制器(Controller)协调模型和视图。理解并运用MVC可以让你的代码结构清晰,...