Java Web并发访问的线程安全问题

10、Java Web开发中的Bean与成员变量使用 本文探讨了Java Web开发中Java Bean在封装数据和默认验证中的应用,以及Servlet中使用成员变量可能引发的线程安全问题。通过实例展示了Bean如何通过访问器实现数据验证,以及控制器如何处理请求并转发到JSP页面。同时,详细分析了成员变量在多线程环境下的潜在问题,并提出了避免或解决这些问题的方法,如使用局部变量或同步块。适合希望了解Web开发中数据处理和线程安全机制的开发者参考。 阅读详情

Java Web并发访问的线程安全问题

2018年05月12日 02:02:52 菜鸟级的IT之路 阅读数:68更多

个人分类: JAVA~JavaWeb

一、Servlet的线程安全问题

Java web服务器下,每个Servlet只有一个实例(即单例模式),导致有多个Http请求发给一个Servlet实例,每个请求是一个线程。如果Servlet有类变量或实例变量,那么该变量就变成了共享资源,当多个线程访问操作该变量时,就有可能存在安全隐患。例如,当一个Http请求在访问该变量的时候,另一个Http请求可能在修改它的值。

解决方法:在Servlet中不要定义类变量或实例变量,如果非定义不可,就需要为操作该变量的所有方法加synchronized修饰符,进行同步控制。

注意: 
1. 在Servlet中可以定义常量 
2. 如果定义的变量只用查询操作,可以不加同步控制 
3. 被Servlet调用的类中(如值对象、领域模型类)中是否可以安全的使用实例变量?如果你在每次方法调用时新建一个对象,再调用它们的方法,则不存在同步问题。因为它们不是多个线程共享的资源,只有共享的资源才需要同步,而Servlet的实例对于多个线程是共享的。

二、Struts并发访问的线程安全问题

同Servlet一样,Struts中的Action也是单例的,所以多Http请求访问时,也存在线程安全问题。

解决方法:同Servlet

三、Spring并发访问的线程安全性问题

和Struts一样,Spring的Controller默认是Singleton的(非线程安全的),这意味着每个request过来,系统都会用原有的instance去处理,这样导致了两个结果:一是我们不用每次创建Controller,二是减少了对象创建和垃圾收集的时间;由于只有一个Controller的instance,当多个线程调用它的时候,它里面的instance变量就不是线程安全的了,会发生窜数据的问题。

当然大多数情况下,我们根本不需要考虑线程安全的问题,除非在Controller中声明了实例变量。因此,我们在使用spring mvc 的contrller时,应避免在controller中定义类变量或实例变量。 

如:

 
  1. public class Controller extends AbstractCommandController {

  2. ......

  3. protected Company company;

  4. protected ModelAndView handle(HttpServletRequest request,HttpServletResponse response,

  5. Object command,BindException errors) throws Exception {

  6. company = ................;

  7. }

  8. }

在这里有声明一个变量company,这里就存在并发线程安全的问题。 
如果控制器是使用单例形式,且controller中有一个私有的变量a,所有请求到同一个controller时,使用的a变量是共用的,即若是某个请求中修改了这个变量a,则在别的请求中能够读到这个修改的内容。。

有几种解决方法: 
1、在Controller中使用ThreadLocal变量 
2、在spring配置文件Controller中声明 scope=”prototype”,每次都创建新的controller。

注意:在Spring mvc中,如果dao、service也是单例的,要避免在Dao和Service类中建立类变量或实例变量。

四、SpringMVC多线程环境中如何保证对象的安全性?

http://linapex.blog.163.com/blog/static/189237516201381493441799/

总结:多线程环境下如果访问单例对象,当对象内部有类变量或实例变量时,就可能存在安全性问题。 
解决方法: 
1.对操作共享变量的所用方法进行同步控制; 
2.同步共享变量,例如Collections.synchronizedMap()可以同步共享的Map。 

3.使用同步对象,例如ConcurrentMap、AtomicInteger等对象都是线程安全的,使用AtomicInteger可以统计系统的并发量。

==========================================================================================

 

在web开发中,要关注由于并发访问所导致的对某一同一个值的修改,否则信息会造成泄漏servlet是在多线程环境下的。即可能有多个请求发给一个servelt实例,每个请求是一个线程。
struts下的action也类似,同样在多线程环境下。可以参考struts user guide: http://struts.apache.org/struts-action/userGuide/building_controller.html 中的Action Class Design Guidelines一节:  Write code for a multi-threaded environment - Our controller servlet creates only one instance of your Action class, and uses this one instance to service all requests. Thus, you need to write thread-safe Action classes. Follow the same guidelines you would use to write thread-safe Servlets. 
    译:为多线程环境编写代码。我们的controller servlet指挥创建你的Action 类的一个实例,用此实例来服务所有的请求。因此,你必须编写线程安全的Action类。遵循与写线程安全的servlet同样的方针。
  
1.什么是线程安全的代码
    在多线程环境下能正确执行的代码就是线程安全的。
    安全的意思是能正确执行,否则后果是程序执行错误,可能出现各种异常情况。

2.如何编写线程安全的代码
    很多书籍里都详细讲解了如何这方面的问题,他们主要讲解的是如何同步线程对共享资源的使用的问题。主要是对synchronized关键字的各种用法,以及锁的概念。
    Java1.5中也提供了如读写锁这类的工具类。这些都需要较高的技巧,而且相对难于调试。
  
    但是,线程同步是不得以的方法,是比较复杂的,而且会带来性能的损失。等效的代码中,不需要同步在编写容易度和性能上会更好些。
  我这里强调的是什么代码是始终为线程安全的、是不需要同步的。如下:
  1)常量始终是线程安全的,因为只存在读操作。
  2)对构造器的访问(new 操作)是线程安全的,因为每次都新建一个实例,不会访问共享的资源。
  3)最重要的是:局部变量是线程安全的。因为每执行一个方法,都会在独立的空间创建局部变量,它不是共享的资源。局部变量包括方法的参数变量。
 struts user guide里有:
    Only Use Local Variables - The most important principle that aids in thread-safe coding is to use only local variables, not instance variables , in your Action class.
   译:只使用用局部变量。---编写线程安全的代码最重要的原则就是,在Action类中只使用局部变量,不使用实例变量。

 
总结:
     在Java的Web服务器环境下开发,要注意线程安全的问题。最简单的实现方式就是在Servlet和Struts Action里不要使用类变量、实例变量,但可以使用类常量和实例常量。
如果有这些变量,可以将它们转换为方法的参数传入,以消除它们。
     注意一个容易混淆的地方:被Servlet或Action调用的类中(如值对象、领域模型类)中是否可以安全的使用实例变量?如果你在每次方法调用时
新建一个对象,再调用它们的方法,则不存在同步问题---因为它们不是多个线程共享的资源,只有共享的资源才需要同步---而Servlet和Action的实例对于多个线程是共享的。
    换句话说,Servlet和Action的实例会被多个线程同时调用,而过了这一层,如果在你自己的代码中没有另外启动线程,且每次调用后续业务对象时都是先新建一个实例再调用,则都是线程安全的。

手把手教你用CsvView分析大疆无人机飞行日志(附实战CTF题解) 本文详细介绍了如何使用CsvView工具分析大疆无人机飞行日志,包括环境搭建、日志提取、核心功能解析及CTF实战技巧。通过实战案例,帮助读者掌握无人机取证的关键技术,提升日志分析能力,特别适合网络安全竞赛和实际取证场景。 阅读详情

相关推荐

Tip-Adapter: Training-free Adaption of CLIP for Few-shot Classification

对比式视觉-语言预训练,也称为CLIP,通过大规模的图像-文本对来学习视觉表示,为zero-shot知识迁移展示了新的范式。它在下游任务上展现出令人瞩目的性能,实现了zeri-shot的知识迁移。为了进一步增强CLIP的适应能力,现有方法提出了微调可学习模块的方法,显著提高了少样本情况下的性能,但也引入了额外的训练时间和计算资源。在本文中,我们提出了一种适用于CLIP的无需训练的少样本分类方法,称为Tip-Adapter。

qq_43800752的博客 1163

4、并发问题的了解(多线程的线程安全问题)

【代码】4、并发问题的了解(多线程的线程安全问题) 就是多个线程操作同一个资源的情况:线程不安全。

分享JAVA/ Python/ Ts学习路上的一些笔记,不足之处多多见谅。 300

最速下降法、牛顿法、拟牛顿法,Python实现高维二次目标函数优化

原理什么的就不说了,只有代码。。。 十元二次目标函数,求极小值点。 1.最速下降法 import random import numpy as np import matplotlib.pyplot as plt from sympy import * def goldsteinsearch(f, df, d, x, alpham, rho, t): flag = 0 a = 0 b = alpham fk = f(x) gk = df(x)

我乐飞的技术博客 2243

Spring 并发访问的线程安全性问题

首先对于Spring的IOC来说,对象是由Spring来帮我们管理,也就是在Spring启动的时候,在Spring容器中,由Spring给我们创建的,Spring会帮我们维护,一般都是单例的,也就是一个对象。spring生成对象默认是单例的。通过scope属性可以更改为多例。 下面我们来一个网上的例子: package test; import java.util.Date; impor

何静媛 3万+

Doris存储层设计介绍2——数据写入及删除流程

Doris存储层设计介绍2——数据写入及删除流程

爱吃辣条的博客 4588

Android Audio - 支持多应用同时录音_Android8.1修改方法

支持多应用同时录音_Android8.1修改方法 源码路径: sdk\frameworks\av\services\audiopolicy\managerdefault\AudioPolicyManager.cpp 需要修改两个位置: audio_io_handle_t AudioPolicyManager::getInputForDevice() 在mpClientInterface-&gt...

iFinelio Tower 的博客 5758

多线程的安全问题

1、共享带来的问题 多个线程在临界区内执行,由于代码的执行序列不同而导致结果无法预测。 临界区 一个程序运行多个线程本身是没有问题的 问题出在多个线程访问共享资源。在多个线程对共享资源读写操作时发生指令交错,就会出现问题。一段代码块内如果存在对共享资源的多线程读写操作,称这段代码块为临界区。 static int counter = 0; static void increment() // 临界区 { counter++; } static void decrement() // 临界区 { coun

myjess’s blog 559

[官方培训]07-UE材质基础 孙丹璐 Epic 笔记

勾选允许自定义深度写入再在模型上勾选然后可以通过Scene Texture节点拿到渲染的自定义深度信息,有了自定义深度信息就可以与当前渲染的像素深度进行对比,自定义深度信息存放的是最靠近我们的深度,如果当前像素离自定义深度比较远我们就不要这个像素。效果如下这种方案的缺点也很明显,因为这样看不到第二层的透明了,如果是两层的半透明的裙摆,这样就看不到第二层的裙摆了。对于半透明排序问题最根本能解决的还是光线追踪,ue5中又加入了OIT(基于像素的排序)。官方透明材质的理解和应用。

Tcohneyn的博客 1562

SpringMVC下,多个请求线程安全问题

SpringMVC下,多个请求线程安全问题

chengbo_eva的博客 650

vivado下ECO操作-不重新综合实现修改属性并生成.bit

ECO即engineer change order,即工程变更指令,可以对设计做局部小改动并只对改动部分重新布局布线并生成.bit。在一个工程动辄编译几个小时情况下,可以在调试中节省大量时间。比如我们在调试中,需要改变时钟占空比或者相位,需要改变寄存器初值等等,此时用ECO暂时改动,待验证后在重新编译无疑是最有效率的方法。 实现ECO通常有两种方式,一是通过vivado界面完成,另一种方法就是tcl脚本。所有的ECO操作都可以通过tcl操作完成,有的操作用vivado界面无法完成,只能通过tcl。以下主要

4657

【同等学力】2005-数学⭐✨

有r个正方形排成一行,今用红、黄、白、蓝四种颜色给这个r个正方形染色,每个正方形只能染一种颜色,如果要求染红、黄、白色的正方形分别至少出现一个,问有多少种不同的染法?3、(4分)设G是一个有n个结点m条边的连通简单平面图,若n≥3,则m≤3n-6.4、(4分)证明:任何连通简单平面图至少有一个结点的度数不超过5

super_mochi1 306

【Javaweb】线程安全详解

一、观察线程的所有状态 线程的状态是一个枚举类型 Thread.State public static void main(String[] args) { for (Thread.State state : Thread.State.values()){ System.out.println(state); } } NEW: 安排了工作, 还未开始行动 RUNNABLE: 可工作的. 又可以分成正在工作中和即将开始工作.就绪状态

耀的博客 3348

多模型动态路由(Fusion):从“算力霸权”到“架构分权”的工程范式转型

多模型动态路由(Multi-Model Dynamic Routing)是指在多个大语言模型之间,根据请求特征、资源约束和业务目标,动态选择最优模型或模型组合的技术范式。传统网关擅长管理请求流量,但不理解“任务类型”。而AI路由层需要对每个请求进行语义理解、能力匹配和成本评估。从“算力霸权”到“架构分权”,这不是技术的线性演进,而是工程范式的根本转型。过去三年,开发者的核心能力是“选对模型”——在GPT、Claude、Gemini之间做出正确选择。

ZDQ58818的博客 74

java web 中并发访问的线程安全

前言:最近在学习《Java并发编程实战》 感觉是有一定的难度。正在努力的理解如何编写多线程安全的程序。 发现线程不安全的核心:对共享数据的修改 这就联想到了 Java web ,web 所在的环境就是高并发的,那么如何在高并发的环境下保证自己的web 项目是安全的??? 一:web服务器 接收请求时的线程情况 web 服务器处理请求的几种模式: 收到一个请求就处理,此时不能处理其他的请求,直...

Stitch__的博客 660

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

Servlet的线程安全问题

一个web应用可能被来自四面八方的客户并发访问,而且有可能这些客户并发访问的是web应用中的同一个Servlet。Servlet容器为了保证能同时响应多个客户的要求访问同一个Servlet的HTTP请求,通常会为每一个请求分配一个工作线程,这些工作线程并发执行同一个Servlet对象的service方法,这就可能带来线程安全问题。 1. 第一种情况:利用Java的同步机制 因为Servlet也

confirmAname的专栏 984

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

聊聊Servlet、Struts1、Struts2以及SpringMvc中的线程安全

前言 很多初学者,甚至是工作1-3年的小伙伴们都可能弄不明白?servlet Struts1 Struts2 springmvc 哪些是单例,哪些是多例,哪些是线程安全? 在谈这个话题之前,我们先了解一下Java中相关的变量类型以及内存模型JMM。 变量类型 类变量:独立于方法之外的变量,用 static 修饰。 局部变量:类的方法中的变量。 ...

weixin_33755847的博客 209

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

Servlet线程安全性解析

Servlet:单实例多线程,也可以认为是单进程多线程的运行在容器中。线程不安全,因为被多个线程访问一个实例,共享的数据可能会发生安全问题。         每个客户端访问Servlet时,都是一个独立的线程。         概述          在探讨java线程安全前,让我们先简要介绍一下Java语言。  任何语言,如C++,C#,Java,它们都有相通之处,特别是语法,但

sunbobo163的专栏 709

Servlet的线程安全

Servlet的多线程机制

小李专栏 2370

线程安全与并发安全探究(三)--servlet多线程并发问题

Servlet/JSP技术和ASP、PHP等相比,由于其多线程运行而具有很高的执行效率。由于Servlet/JSP默认是以多线程模式执行的,所以,在编写代码时需要非常细致地考虑多线程的安全性问题。然而,很多人编写Servlet/JSP程序时并没有注意到多线程安全性的问题,这往往造成编写的程序在少量用户访问时没有任何问题,而在并发用户上升到一定值时,就会经常出现一些莫明其妙的问题。   Serv

dongping_share的专栏 528

java web服务器开发笔记

http://blog.sina.com.cn/s/blog_81890d830101f6jw.html JAVA EE Eclipse下配置Tomcat服务器   http://www.cnblogs.com/xdp-gacl/p/3760336.htmljava web博客系列 synchronized (this) {} 这种做法虽然解决了线程安全问题,但是编写Servlet却万万

zhangjiajie023的专栏 639

Servlet 线程安全问题

1、Servlet的特点:单实例多线程 Servlet(struts类似)的生命周期是由Web容器负责的,当客户端第一次请求Servlet时,容器负责初始化Servlet,也就是实例化这个Servlet 类。 以后这个实例就负责多个客户端的请求,一般不会再实例化一个Servlet类,也就是有多个线程在使用这个实例。 Servlet之所以比CGI效率高就是因为Servlet是多线程的。

longteng2011的专栏 678

Servlet的多线程机制与线程安全

一般选择在这样的列上创建索引: 1. 在经常需要搜索查询的列上创建索引,可以加快搜索的速度; 2. 在作为主键的列上创建索引,强制该列的唯一性和组织表中数据的排列结构; 3. 在经常用在连接的列上创建索引,这些列主要是一些外键,可以加快连接的速度; 4. 在经常需要根据范围进行搜索的列上创建索引,因为索引已经排序,其指定的范围是连续的; 5. 在经常需要排序的列上创建索引,因为索引已经

john2522的专栏 2650

servlet线程安全问题

1.线程安全问题产生的原因 我们知道一般我们的自己写的servlet类在servlet容器中只有一个对象,而每一个客户端发送过来一个请求,servlet容器就会为其创建一个线程 当多个客户端请求访问同一个servlet时候就有可能发生线程安全问题。 2.servlet线程安全问题的演示 不会产生线程安全问题的 转载于:https://www.cnblogs.com/cmc666/p/761...

weixin_30666753的博客 56
上一篇: Java 单例模式线程安全问题
下一篇: Java中线程安全的单例模式
javaPie
博客等级 码龄16年 1171粉丝 43原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值