jmm 和线程安全
Java的内存模型JMM
Java的内存模型JMM(Java Memory Model)JMM主要是为了规定了线程和内存之间的一些关系。根据JMM的设计,系统存在一个主内存(Main Memory),Java中所有实例变量都储存在主存中,对于所有线程都是共享的。每条线程都有自己的工作内存(Working Memory),工作内存由缓存和堆栈两部分组成,缓存中保存的是主存中变量的拷贝,缓存可能并不总和主存同步,也就是缓存中变量的修改可能没有立刻写到主存中;堆栈中保存的是线程的局部变量,线程之间无法相互直接访问堆栈中的变量。根据JMM,我们可以将论文中所讨论的Servlet实例的内存模型抽象为下图所示的模型。
Servlet的线程安全问题
Servlet的线程安全问题主要是由于实例变量使用不当而引起的,这里以一个现实的例子来说明。
/**
* 模拟用户AB在同时执行不同的动作
* 先执行 http://localhost:8080/concurrent?username=A&action=play
* 稍后执行 http://localhost:8080/concurrent?username=B&action=eat
*/
public class Concurrent extends HttpServlet {
private static final long serialVersionUID = 1L;
private String action = "";//动作
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
try {
String username = request.getParameter("username");
action = request.getParameter("username");
Thread.sleep(5000); //为了突出并发问题,在这设置一个延时
//如果不出意外,应该用户AB都在吃饭
System.out.println("用户:"+username+"在"+action);
} catch (Exception e) {
}
}
}
Struts1
首先,明确一点Sturts1 action是单例模式,线程是不安全的。Struts1使用的ActionServlet是单例的,既然是单例,当使用实例变量的时候就会有线程安全的问题。所有一般在开发中试禁止使用实例变量的。
Struts2
struts2使用的是actionContext,都是使用里面的实例变量,让struts2自动匹配成对象的。每次处理一个请求,struts2就会实例化一个对象,这样就不会有线程安全的问题了。
需要注意的是,如果struts2+spring来管理注入的时候,不要把Action设置成单例,否则会出问题的。当然现在很少有项目使用struts2了。
SpringMVC
SpringMVC的controller默认是单例模式的,所以也会有多线程并发的问题。
总结
servlet Struts1 SpringMvc 是线程不安全的,当然如果你不使用实例变量也就不存在线程安全的问题了。
Struts2 是线程安全的,当然前提情况是,Action 不交给 spring管理,并且不设置为单例。
SpringMvc 的 Bean 可以设置成多例变成线程安全,但是一定程度上回影响系统性能。
jmm 和线程安全的更多相关文章
- 【Java线程】Java内存模型总结
学习资料:http://www.infoq.com/cn/articles/Java-memory-model-1 Java的并发采用的是共享内存模型(而非消息传递模型),线程之间共享程序的公共状态, ...
- (转)【Java线程】Java内存模型总结
Java的并发采用的是共享内存模型(而非消息传递模型),线程之间共享程序的公共状态,线程之间通过写-读内存中的公共状态来隐式进行通信.多个线程之间是不能直接传递数据交互的,它们之间的交互只能通过共享变 ...
- JMM随笔
What? Java内存模型(Java Memory Model,JMM)主要是为了规定了线程和内存之间的一些关系. 根据JMM的设计: 系统存在一个主内存(Main Memory),Java中所有变 ...
- 深入理解JMM(Java内存模型) --(三)顺序一致性
数据竞争与顺序一致性保证 当程序未正确同步时,就会存在数据竞争.Java内存模型规范对数据竞争的定义如下: 在一个线程中写一个变量, 在另一个线程读同一个变量, 而且写和读没有通过同步来排序. 当代码 ...
- Java线程之Java内存模型(jmm)
一.Java内存模型(jmm) 线程通信 消息传递 重排序 顺序一致性 Happens-Before As-If-Serial
- Java线程之基础
Java内存模型(jmm) 线程通信 消息传递 重排序 顺序一致性 Happens-Before As-If-Serial 一.线程的生命周期及五种基本状态 线程生命周期:新建.就绪.运行.阻塞.死亡 ...
- Java并发指南2:深入理解Java内存模型JMM
本文转载自互联网,侵删 一:JMM基础与happens-before 并发编程模型的分类 在并发编程中,我们需要处理两个关键问题:线程之间如何通信及线程之间如何同步(这里的线程是指并发执行的活动实 ...
- 并发和多线程(二)--启动和中断线程(Interrupt)的正确姿势
启动线程: 从一个最基本的面试题开始,启动线程到底是start()还是run()? Runnable runnable = () -> System.out.println(Thread.cur ...
- Java并发读书笔记:JMM与重排序
目录 Java内存模型(JMM) JMM抽象结构 重排序 源码->最终指令序列 编译器重排序 处理器重排序 数据依赖性 as-if-serial happens-before happens-b ...
随机推荐
- Java Web项目部署时 “Exploded Archive”模式部署时无效
在myeclipse中部署项目时,当Deploy type为Exploded Archive(deveplopment mode)时,finish按钮为灰色,无法部署的解决方法: 1.project上 ...
- oc调javascript方法(evaluateJavaScript:)&&js给oc发通知
在ios8中引入了WKWebView控件,通过在头文件引用 #import <WebKit/WebKit.h>来使用该控件, 这个控件与oc的原生控件uiwebview很相似,它更方便oc ...
- mongoDb CPU利用率100%的分析和解决
在公司的项目中,突然出现过一个情况,mongodb 的CPU利用率到达100%,导致服务器这边卡死了,请求了半天无响应,提示请求超时. 因为,当时APP用户可能会在某一个时间段集中的使用,所以,请求量 ...
- C#中的索引器
在Java中,一般会这样使用get,set方法: class Person{ private String name; public void setName(String name){ this.n ...
- js读取本地txt文件中的json数据
list.txt内容 [ {"optionKey":"1", "optionValue":"Canon in D"}, ...
- u-boot2011.09 启动流程记录
start arch/arm/cpu/armv7/start.S 36 .globl _start 37 _start: b reset 136 reset: 137 bl save_boot_par ...
- keras系列︱人脸表情分类与识别:opencv人脸检测+Keras情绪分类(四)
引自:http://blog.csdn.net/sinat_26917383/article/details/72885715 人脸识别热门,表情识别更加.但是表情识别很难,因为人脸的微表情很多,本节 ...
- Spark算子总结(带案例)
Spark算子总结(带案例) spark算子大致上可分三大类算子: 1.Value数据类型的Transformation算子,这种变换不触发提交作业,针对处理的数据项是Value型的数据. 2.Key ...
- Navi.Soft31.WinForm框架(含下载地址)
1概述 1.1应用场景 尽管互联网高速发展,互联网软件也随之越来越多,但桌面应用程序在某些领域中还是不可替代,如MIS,ERP,CRM等软件产品,同时,这类软件均包括一些通用的功能,如:与数据库操作, ...
- JS Window对象操作思维导图