文档章节

spring 单例 并发访问

重城重楼
 重城重楼
发布于 04/30 14:01
字数 1634
阅读 52
收藏 0

一、TOMCAT 并发请求

1、tomcat模式有 BIO、NIO、APR三种模式,操作系统对进程的线程数有限制,Windows:2000,linux:1000;Tomcat默认配置的最大请求数是150,[即150个bio线程],远超过150的最好就采取集群

2、BIO模式,即阻塞IO,默认配置。

         server.xml:<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />

         每个请求都需要创建一个线程进行处理,这种模式下的并发量受到线程数量的限制,胜在模式成熟稳定,BUG极少

3、NIO模式,即非阻塞IO,JAVA NIO实现理论基础,实现较复杂,[建议可采用netty框架来快速实现]

         server.xml:<Connector port="8080" protocol="org.apache.coyote.http11.Http11NioProtocol" connectionTimeout="20000" redirectPort="8443" />

        在性能上高于阻塞式的,每个请求也不用额外创建一个新线程进行处理,并发能力能BIO强;适用于连接数目多且连接比较短(轻操作)的架构,比如聊天服务器,并发局限于应用中,编程比较复杂

4、APR模式,(Apache Portable Runtime/Apache可移植运行库),是Apache HTTP服务器的支持库。当然,apr模式还需要安装 apr 、 apr-utils 、tomcat-native包

        server.xml:<Connector port="8080" protocol="org.apache.coyote.http11.Http11AprProtocol" connectionTimeout="20000" redirectPort="8443" />,

        Tomcat将以JNI的形式调用Apache HTTP服务器的核心动态链接库来处理文件读取或网络传输操作,从而大大地提高Tomcat对静态文件的处理性能。 Tomcat apr也是在Tomcat上运行高并发应用的首选模式。

    bio 信息: Starting ProtocolHandler ["http-bio-8080"] 2013-8-6 16:17:50 org.apache.coyote.AbstractProtocol start

    nio 信息: Starting ProtocolHandler ["http-nio-8080"] 2013-8-6 16:59:53 org.apache.coyote.AbstractProtocol start

    apr 信息: Starting ProtocolHandler ["http-apr-8080"] 2013-8-6 17:03:07 org.apache.coyote.AbstractProtocol start       

Tomcat 6.x版本从6.0.32开始就默认支持apr。
 Tomcat 7.x版本从7.0.30开始就默认支持apr。
 因此,所以高版本tomcat在Windows下启动的日志中看到的多是http-apr-8080-的线程日志

===========分割线,bio线程是池模式复用的,所以一个bio线程可以承载多次request请求==========================

二、spring 单例 @controller、@service

        1、spring框架controller和service默认都是单例的,那么多并发bio时,是如何实现线程安全的?    线程与栈:

             A、每当启用一个线程时,JVM就为他分配一个Java栈,栈是以帧为单位保存当前线程的运行状态。某个线程正在执行的方法称为当前方法,当前方法使用的栈帧称为当前帧,当前方法所属的类称为当前类,当前类的常量称为当前常量池。当线程执行一个方法时,它会跟踪当前常量池。
             B、每当线程调用一个Java方法时,JVM就会在该线程对应的栈中压入一个帧,这个帧自然就成了当前帧。当执行这个方法时,它使用这个帧来存储参数、局部变量、中间运算结果等等。
             C、Java栈上的所有数据都是私有的。任何线程都不能访问另一个线程的栈数据。所以我们不用考虑多线程情况下栈数据访问同步的情况。

             D、如上,则@Controller是单例模式,即一个对象只有一个实例。通过线程副本[栈]的模式实现并发访问

        2、线程副本与安全问题  线程副本通过栈和帧实现线程隔离,达到并发访问的目的,那么有没有前提呢?

            A、如上二-1-B所述,局部变量和中间运算结果集参数是线程隔离==>安全的,但是成员变量则是会受到多线程调用影响的

            B、那Controller里面的service都是成员变量,会受影响么?service也是单例,其主要用来实现方法调用,就会进入帧的切换从而转变为中间结果的问题,同理单例的service的成员变量和局部变量的线程隔离性同Controller。

                PS:Spring对一些Bean(如RequestContextHolder、TransactionSynchronizationManager、LocaleContextHolder等)中非线程安全状态采用ThreadLocal进行处理,让它们也成为线程安全的状态。

                        https://my.oschina.net/ysma1987/blog/2885611 记录了AOP切面中获取request方式的原理就是据此而来

                        TransactionSynchronizationManager对资源resources采用ThreadLocal保管,就是dao的SqlSession[亦即getConnection]的由来

            C、对应的成员变量就被暴露在所有线程面前了,所以最好用ThreadLocal保护起来,实现线程安全。

                 PS:https://my.oschina.net/ysma1987/blog/3034499 描述了ThreadLocal在此种模式下的坑

三、单例应用场景

            A、有状态和无状态的对象基本概念: 

                    有状态对象(Stateful Bean),就是有实例变量的对象 ,可以保存数据,是非线程安全的。一般是prototype scope。

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

                    Service和Dao就都是无状态对象,适用于单例场景,如果有资源操作的限制,就涉及同步器、锁等操作了

==========分割线,后续与单例的并发访问就无太大关系了,属于额外问题的7延伸==================

三、多线程与事务的藕断丝连

                事务管理器用于管理各个事务方法,它产生一个事务管理上下文。下文以SpringJDBC的事务管理器DataSourceTransactionManager类为例

                spring七个事务传播属性[PROPAGATION_REQUIRED等]和五个隔离级别[ISOLATION_DEFAULT 等]

                 我们知道数据库连接Connection在不同线程中是不能共享的,事务管理器为不同的事务线程利用ThreadLocal类提供独立的Connection副本。事实上,它将Service和Dao中所有线程不安全的变量都提取出来单独放在一个地方,并用ThreadLocal替换。而多线程可以共享的部分则以单实例方式存在。

                延伸问:事务个默认隔离属性和和默认传播属性是什么?以及在多线程中的影响?

========================分割线===================================

参考文档:https://blog.csdn.net/liumohan0806/article/details/72723205

                https://blog.csdn.net/qq_41173453/article/details/81195997

                https://blog.csdn.net/mrleeapple/article/details/80420395

                https://2277259257.iteye.com/blog/2300298

                https://blog.csdn.net/baidu_37107022/article/details/75578140[事务]

© 著作权归作者所有

重城重楼
粉丝 4
博文 59
码字总数 45991
作品 0
南京
程序员
私信 提问
springmvc多线程

大家好,springmvc中并发访问service会造成线程不安全吗?没有成员变量,我现在的场景是,请求到达时,先执行一个service进行一个判断,如果并发量很大的时候,这个service安全吗?我记得bea...

樱木花道VS康
2018/05/30
508
1
一道78%的Java程序员搞不清的Spring bean面试题

熟悉Spring开发的朋友都知道Spring提供了5种scope分别是singleton、prototype、request、session、global session。 如下图是官方文档上的截图,感兴趣的朋友可以进去看看这五种分别有什么不...

Java架构师追风
08/08
0
0
SpringMVC和Struts的区别

springmvc是单例,非线程安全 Struts2是线程安全的对每个请求都产生一个实例 springmvc的入口是Servlet,而Struts2的filter spring的前段控制器是DispatcherServlet Struts2的前端的核心控制...

ZR520
2016/11/03
43
0
java SSH 并发问题

当我们利用SSH做项目的时候,Struts2的action是交给Spring来管理的,但是Spring的bean又是单例,这样的话就会引起现在并发问题,我们该怎么解决并发,还是Spring他自己会去解决...

wlg910525
2014/03/24
1K
14
小弟今天看Spring突然有个问题没有想明白,求高手解答:

Spring的Bean默认都是单例的,那么Spring是如何解决在大并发下单例bean的线程安全呢?希望能详尽一点,小弟感激不尽。谢谢

二十岁以后
2017/12/13
373
3

没有更多内容

加载失败,请刷新页面

加载更多

用 Sphinx 搭建博客时,如何自定义插件?

之前有不少同学看过我的个人博客(http://python-online.cn),也根据我写的教程完成了自己个人站点的搭建。 点此:使用 Python 30分钟 教你快速搭建一个博客 为防有的同学不清楚 Sphinx ,这...

王炳明
昨天
2
0
黑客之道-40本书籍助你快速入门黑客技术免费下载

场景 黑客是一个中文词语,皆源自英文hacker,随着灰鸽子的出现,灰鸽子成为了很多假借黑客名义控制他人电脑的黑客技术,于是出现了“骇客”与"黑客"分家。2012年电影频道节目中心出品的电影...

badaoliumang
昨天
10
0
很遗憾,没有一篇文章能讲清楚线程的生命周期!

(手机横屏看源码更方便) 注:java源码分析部分如无特殊说明均基于 java8 版本。 简介 大家都知道线程是有生命周期,但是彤哥可以认真负责地告诉你网上几乎没有一篇文章讲得是完全正确的。 ...

彤哥读源码
昨天
13
0
jquery--DOM操作基础

本文转载于:专业的前端网站➭jquery--DOM操作基础 元素的访问 元素属性操作 获取:attr(name);$("#my").attr("src"); 设置:attr(name,value);$("#myImg").attr("src","images/1.jpg"); ......

前端老手
昨天
6
0
Django的ChoiceField和MultipleChoiceField错误提示,选择一个有效的选项

在表单验证时提示错误:选择一个有效的选项 例如有这样一个表单: class ProductForm(Form): category = fields.MultipleChoiceField( widget=widgets.SelectMultiple(), ...

编程老陆
昨天
13
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部