文档章节

单例和多例

杨肥麻
 杨肥麻
发布于 2017/07/10 23:55
字数 1615
阅读 10
收藏 0
点赞 0
评论 0

单例:就是只有一个实例。单例模式确保一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。这个类称为单例类。

多例:对这个bean的每次请求都会创建一个新的bean实例,类似于new。

Spring中,bean可以被定义为两种模式:prototype(多例)和singleton(单例)Spring bean 默认是单例模式。

1.何时用单例?何时用多例?

struts是基于类的属性进行发的,定义属性可以整个类通用,所以默认是多例,不然多线程访问肯定是共用类里面的属性值的,肯定是不安全的。

struts2来说,action必须用多例,因为action本身含有请求参数的值,即可改变的状态;
 STRUTS1来说,action则可用单例,因为请求参数的值是放在actionForm中,而非action中的;

springmvc是基于方法的开发,都是用形参接收值,一个方法结束参数就销毁了,多线程访问都会有一块内存空间产生,里面的参数也是不会共用的,所有springmvc默认使用了单例,所以controller里面不适合在类里面定义属性,只要controller中不定义属性,那么单例完全是安全的。

2.如何产生单例多例?

 单例在spring中是默认的,如果要产生多例,则在配置文件的bean中添加scope="prototype"; 

3.为什么用单例多例:
    之所以用单例,是因为没必要每个请求都新建一个对象,这样子既浪费CPU又浪费内存;
   之所以用多例,是为了防止并发问题;即一个请求改变了对象的状态,此时对象又处理另一个请求,而之前请求对对象状态的改变导致了对象对另一个请求做了错误的处理;
    用单例和多例的标准只有一个:
    当对象含有可改变的状态时(更精确的说就是在实际应用中该状态会改变),则多例,否则单例;

4.ThreadLocal和线程同步机制的比较

ThreadLocal和线程同步机制都是为了解决多线程中相同变量的访问冲突问题。 

同步机制中,通过对象的锁机制保证同一时间只有一个线程访问变量。这时该变量是多个线程共享的,使用同步机制要求程序慎密地分析什么时候对变量进行读写,什么时候需要锁定某个对象,什么时候释放对象锁等繁杂的问题,程序设计和编写难度相对较大。 

ThreadLocal则从另一个角度来解决多线程的并发访问。ThreadLocal会为每一个线程提供一个独立的变量副本,从而隔离了多个线程对数据的访问冲突。因为每一个线程都拥有自己的变量副本,从而也就没有必要对该变量进行同步了。ThreadLocal提供了线程安全的共享对象,在编写多线程代码时,可以把不安全的变量封装进ThreadLocal。 

概括起来说,对于多线程资源共享的问题,同步机制采用了“以时间换空间”的方式,而ThreadLocal采用了“以空间换时间”的方式。

5.Spring使用ThreadLocal解决线程安全问题 

一般情况下,只有无状态的Bean才可以在多线程环境下共享,在Spring中,绝大部分Bean都可以声明为singleton作用域。就是因为Spring对一些Bean(如RequestContextHolder、TransactionSynchronizationManager、LocaleContextHolder等)中非线程安全状态采用ThreadLocal进行处理,让它们也成为线程安全的状态,因为有状态的Bean就可以在多线程中共享了。 

ThreadLocal比直接使用synchronized同步机制解决线程安全问题更简单,更方便,且结果程序拥有更高的并发性。

线程安全问题都是由全局变量及静态变量引起的。  

若每个线程中对全局变量、静态变量只有读操作,而无写操作,一般来说,这个全局变量是线程安全的;若有多个线程同时执行写操作,一般都需要考虑线程同步,否则就可能影响线程安全。

1) 常量始终是线程安全的,因为只存在读操作。 

2)每次调用方法前都新建一个实例是线程安全的,因为不会访问共享的资源。

3)局部变量是线程安全的。因为每执行一个方法,都会在独立的空间创建局部变量,它不是共享的资源。局部变量包括方法的参数变量和方法内变量。

有状态就是有数据存储功能。有状态对象(Stateful Bean),就是有实例变量的对象  ,可以保存数据,是非线程安全的。在不同方法调用间不保留任何状态。

无状态就是一次操作,不能保存数据。无状态对象(Stateless Bean),就是没有实例变量的对象  .不能保存数据,是不变类,是线程安全的。

有状态对象:

无状态的Bean适合用不变模式,技术就是单例模式,这样可以共享实例,提高性能。有状态的Bean,多线程环境下不安全,那么适合用Prototype原型模式。Prototype: 每次对bean的请求都会创建一个新的bean实例。

Struts2默认的实现是Prototype模式。也就是每个请求都新生成一个Action实例,所以不存在线程安全问题。需要注意的是,如果由Spring管理action的生命周期, scope要配成prototype作用域。

package com.baobaotao.basic;   

public class SequenceNumber {   

//①通过匿名内部类覆盖ThreadLocal的initialValue()方法,指定初始值   

private static ThreadLocal<Integer> seqNum = new ThreadLocal<Integer>(){   

public Integer initialValue(){   

return 0;   

}   

};   

//②获取下一个序列值   

public int getNextNum(){   

seqNum.set(seqNum.get()+1);   

return seqNum.get();   

}   

public static void main(String[] args)   

{   

SequenceNumber sn = new SequenceNumber();   

//③ 3个线程共享sn,各自产生序列号   

TestClient t1 = new TestClient(sn);   

TestClient t2 = new TestClient(sn);   

TestClient t3 = new TestClient(sn);   

t1.start();   

t2.start();   

t3.start();   

}   

private static class TestClient extends Thread   

{   

private SequenceNumber sn;   

public TestClient(SequenceNumber sn) {   

this.sn = sn;   

}   

public void run()   

{   

for (int i = 0; i < 3; i++) {//④每个线程打出3个序列值   

System.out.println("thread["+Thread.currentThread().getName()+   

"] sn["+sn.getNextNum()+"]");   

}   

}   

}   

}   

 

本文转载自:http://www.cnblogs.com/doit8791/p/4093808.html

共有 人打赏支持
杨肥麻
粉丝 1
博文 53
码字总数 30289
作品 0
深圳
单例多例需要搞明白两个问题

什么是单例多例; 2. 如何产生单例多例; 3. 为什么要用单例多例 4. 什么时候用单例,什么时候用多例; 1. 什么是单例多例: 所谓单例就是所有的请求都用一个对象来处理,比如我们常用的servi...

Pig-man
2016/04/09
103
0
设计模式C#描述——单例与多例模式

设计模式C#描述——单例与多例模式 作为对象的创建模式,单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。这个类称为单例类。 单例模式有以下特点: 单例类只能...

晨曦之光
2012/03/09
58
0
struts2多例springMVC单例

struts2的控制类action是多例的 springMVC的控制器类Controller是单例的 struts2和springMVC区别在于对数据的处理不同,struts2以属性形式绑定数据,因此必须多例才不会数据混乱。 springMV...

LYQ1990
2016/05/24
158
0
spring IOC部分源码解析

一:原理 当bean是单例时,从缓存获取单例bean;如果没有,则创建单例bean,创建单例bean时用反射获取bean的构造器,通过构造器实例化bean,然后在组装bean,组装bean的时候进行依赖注入;之...

cw134876
04/26
0
0
Spring MVC Controller单例陷阱

Spring MVC Controller默认是单例的: 单例的原因有二: 1、为了性能。 2、不需要多例。 1、这个不用废话了,单例不用每次都new,当然快了。 2、不需要实例会让很多人迷惑,因为spring mvc官...

动听的椰子
2016/02/29
94
0
如何保证rest接口安全性?欢迎解答啊~~

什么是J2SE? J2SE 包含哪些东东? -- java 基础。 如何保证rest接口安全性? hashMap key 可以为空吗? -- 可为空(""),也可为null . arrayList 和 hashMap 有序吗? -- arrayList 有序,可有...

klog
2016/11/04
45
0
spring接口 BeanFactoryAware,动态获取IOC容器里面的对象(多例)

spring默认是单例,有时候我们需要多例。但使用了spring又不能手动new一个。 那么我们就要手动去IOC里取一个对象 首先实现BeanFactoryAware 重写方法

HeyS1
2016/12/04
22
0
为什么jfinal的控制器不用单例模式

1,为什么jfinal的控制器不用单例模式的?虽然多例避免了线程安全的问题,但是假设访问量很大的话,将会创建很多对象,占用大量内存,性能就会下降。 2,单例模式-----一个请求------创建一个...

rakshasa
2015/01/14
2.6K
4
struts2 单例 多例

struts2中action使用的是多例模式,而service层和dao层使用的是单例模式,为什么?是不是action中存在状态数据,而service层和dao层中不存在状态数据,可以复用,所以单例的?...

Friends8811
2015/09/30
265
0
Struts action的单例与多例

struts 2的Action是多实例的并非单例,也就是每次请求产生一个Action的对象。原因是:struts 2的Action中包含数据,例如你在页面填写的数据就会包含在Action的成员变量里面。如果Action是单实...

supperman
2012/07/16
0
4

没有更多内容

加载失败,请刷新页面

加载更多

下一页

存储结构分四类:顺序存储、链接存储、索引存储 和 散列存储

存储结构分四类:顺序存储、链接存储、索引存储 和 散列存储 存储结构分四类:顺序存储、链接存储、索引存储 和 散列存储。 顺序结构和链接结构适用在内存结构中。 顺序表每个单元都是按物理...

DannyCoder
19分钟前
0
0
Firefox 61已经为Ubuntu 提供支持

最新和最好的Mozilla Firefox 61 “Quantum”网络浏览器已经为Ubuntu Linux操作系统的用户提供了支持,现在可以通过官方软件库进行更新。 Mozilla于2018年6月26日发布了Firefox 61版本,该版...

六库科技
45分钟前
0
0
Win10升级后执行系统封装(Sysprep)报错

开始封装 一年多以前开始给公司封装Win10系统,便于统一给公司电脑初始化携带各种软件的系统,致力于装完既可以开发的状态。那时候最新的版本是Win10 1703版本,自然就以他为母盘,然后结合V...

lyunweb
今天
39
0
php 性能优化

#什么情况下会遇到性能问题 PHP 语法使用的不恰当

to_be_better
今天
0
0
Jenkins 构建触发器操作详解

前言 跑自动化用例每次用手工点击jenkins出发自动化用例太麻烦了,我们希望能每天固定时间跑,这样就不用管了,坐等收测试报告结果就行。 一、定时构建语法 * * * * * (五颗星,中间用空格隔...

覃光林
今天
0
0
IDEA配置技巧

超详细设置Idea类注释模板和方法注释模板 idea去掉注解param下划线 JetBrains全系列破解

AK灬
今天
0
0
rsync通过服务同步/Linux系统日志/screen工具

rsync通过服务同步 分为服务端(机器A) 和客户端(机器B) 机器A操作编辑/etc/rsyncd.conf配置文件 [root@yolks1 ~]# vim /etc/rsyncd.conf 文件中添加以下配置 port=873 ...

Hi_Yolks
今天
0
0
分发系统介绍expect脚本远程登录expect脚本远程执行命令 expect脚本传递参数

分发系统介绍 分发系统-expect讲解(也就是一个分发的脚本) 场景: 业务越来越大,网站app,后端,编程语言是php,所以就需要配置lamp或者lnmp,最好还需要吧代码上传到服务器上;但是因为业...

lyy549745
今天
0
0
android studio 中设置创建类时的说明信息(包含 作者 ,创建时间,注释说明等)

今天简单来说一下android studio开发工具中的 一个小设置功能; 在开发过程中我们习惯给新建的类添加一些注释信息,创建日期、时间和作者等。 设置信息 File—>Settings—>Editor—>File and...

切切歆语
今天
0
0
开源监控利器Prometheus初探

前言: Kubernetes作为当下最炙手可热的容器管理平台,在给应用部署运维带来便捷的同时,也给应用及性能监控带来了新的挑战。本文给大家分享一款十分火热的开源监控工具Prometheus,让我们一...

寰宇01
今天
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部