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 和线程安全的更多相关文章

  1. 【Java线程】Java内存模型总结

    学习资料:http://www.infoq.com/cn/articles/Java-memory-model-1 Java的并发采用的是共享内存模型(而非消息传递模型),线程之间共享程序的公共状态, ...

  2. (转)【Java线程】Java内存模型总结

    Java的并发采用的是共享内存模型(而非消息传递模型),线程之间共享程序的公共状态,线程之间通过写-读内存中的公共状态来隐式进行通信.多个线程之间是不能直接传递数据交互的,它们之间的交互只能通过共享变 ...

  3. JMM随笔

    What? Java内存模型(Java Memory Model,JMM)主要是为了规定了线程和内存之间的一些关系. 根据JMM的设计: 系统存在一个主内存(Main Memory),Java中所有变 ...

  4. 深入理解JMM(Java内存模型) --(三)顺序一致性

    数据竞争与顺序一致性保证 当程序未正确同步时,就会存在数据竞争.Java内存模型规范对数据竞争的定义如下: 在一个线程中写一个变量, 在另一个线程读同一个变量, 而且写和读没有通过同步来排序. 当代码 ...

  5. Java线程之Java内存模型(jmm)

    一.Java内存模型(jmm) 线程通信 消息传递 重排序 顺序一致性 Happens-Before As-If-Serial

  6. Java线程之基础

    Java内存模型(jmm) 线程通信 消息传递 重排序 顺序一致性 Happens-Before As-If-Serial 一.线程的生命周期及五种基本状态 线程生命周期:新建.就绪.运行.阻塞.死亡 ...

  7. Java并发指南2:深入理解Java内存模型JMM

    本文转载自互联网,侵删   一:JMM基础与happens-before 并发编程模型的分类 在并发编程中,我们需要处理两个关键问题:线程之间如何通信及线程之间如何同步(这里的线程是指并发执行的活动实 ...

  8. 并发和多线程(二)--启动和中断线程(Interrupt)的正确姿势

    启动线程: 从一个最基本的面试题开始,启动线程到底是start()还是run()? Runnable runnable = () -> System.out.println(Thread.cur ...

  9. Java并发读书笔记:JMM与重排序

    目录 Java内存模型(JMM) JMM抽象结构 重排序 源码->最终指令序列 编译器重排序 处理器重排序 数据依赖性 as-if-serial happens-before happens-b ...

随机推荐

  1. C# 裁剪图片

    /// <summary> /// 生成缩略图 /// </summary> /// <param name="originalImagePath"& ...

  2. 动态可视化 数据可视化之魅D3,Processing,pandas数据分析,科学计算包Numpy,可视化包Matplotlib,Matlab语言可视化的工作,Matlab没有指针和引用是个大问题

    动态可视化 数据可视化之魅D3,Processing,pandas数据分析,科学计算包Numpy,可视化包Matplotlib,Matlab语言可视化的工作,Matlab没有指针和引用是个大问题 D3 ...

  3. java框架篇---struts开发

    1.Token Token主要是以一种指令牌的形式进行重复提交处理的,在很多情况下,如果用户对同一个表单进行了多次提交,则有可能造成数据的混乱,此时,WEB服务器必须可以对这种重复提交的行为做出处理, ...

  4. Java 数据库中文变成问号???解决办法

    在连接的URL地址后面加上: url=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8 于是在正式 ...

  5. 微服务之springCloud-docker-hystrix-dashboard-turbine(九)

    简介 Hystrix的主要优点之一是它收集关于每个HystrixCommand的一套指标.Hystrix仪表板以有效的方式显示每个断路器的运行状况,通过Hystrix Dashboard我们可以在直观 ...

  6. Visual Studio的NuGet包管理器无法加载

    由于网络原因,虽然地址http://www.nuget.org和https://www.nuget.org/api/v2/在浏览器可以正常打开,但是在VS中使用默认的NuGet程序包源经常加载不出来, ...

  7. HTTP1.0/1.1/2.0特性对比_转

    转自:HTTP1.0 HTTP1.1 HTTP2.0 主要特性对比  https://segmentfault.com/a/1190000013028798 HTTP1.0 早先1.0的HTTP版本, ...

  8. NLP-训练个model出来写诗

    2018年新年,腾讯整出来个ai春联很吸引眼球,刚好有个需求让我看下能不能训出来个model来写出诗经一样的文风,求助了下小伙伴,直接丢过来2个github,原话是: 查了一下诗经一共38000个字, ...

  9. CDH版本java开发环境搭建

    1. maven设置 除了阿里云库,还需要引入 cdh, spring库.需要修改maven下面的配置文件setting.xml, 参考下面设置. <mirror> <!--This ...

  10. git 通过nginx 无法clone

    git服务器架设在内网,通过nginx做反向代理后如果公网质量差的话部分项目无法clone,报错: error: RPC failed; result=18, HTTP code = 200B | 3 ...