zoukankan      html  css  js  c++  java
  • Servlet15—— 线程安全问题

    1、什么时候程序会发生线程安全问题?

    • 多线程并发
    • 有共享的数据
    • 共享数据有修改操作

    2、在JVM中,哪些数据可能会存在线程安全问题?

    • 局部变量内存空间不共享,一个线程一个栈,局部变量不会存在线程安全问题
    • 常量不会被修改,所以常量不会存在线程安全问题
    • 所有线程共享一个堆
      • 堆内存中new出来的对象在其中存储,对象内部有“实例变量”,所以“实例变量”的内存多线程是共享的。
      • 实例变量多线程共同访问,并且涉及到修改操作的时候就会存在线程安全问题。
    • 所有线程共享一个方法区
      • 方法区中有静态变量,静态变量的内存也是共享的,若涉及到修改操作,静态变量也存在线程安全问题。

    4、线程安全问题不止是体现在JVM中,还有可能发生在数据库中,例如:多个线程共享同一张表,并且同时去修改表中一些记录,那么这些记录就存在线程安全问题,怎么解决数据库表中数据的线程安全问题呢?

      第一种方案是:在java程序中使用synchronized关键字。线程排队执行,自然不会在数据库中并发,解决线程安全问题。

      第二种方案是:行级锁【悲观锁】

      第三种方案是:事务隔离级别,例如:串行化

      第四种方案是:乐观锁.....

    5、怎么解决线程安全问题

    • 不是用实例变量,尽量使用局部变量
    • 若必须使用实例变量,那么我们可以考虑将该对象变成多例对象,一个线程一个java对象,实例变量的内存也不会共享。
    • 若必须使用单例,那就只能使用synchronized线程同步机制,线程一旦排队执行,则吞吐量降低,降低用户体验。

    6、Servlet线程安全问题及解决方案 (Servlet单实例多线程)

    Servlet体系结构是建立在Java多线程机制之上的,它的生命周期是由Web容器负责的。当客户端第一次请求某个Servlet时,Servlet容器将会根据web.xml配置文件实例化这个Servlet类。当有新的客户端请求该Servlet时,一般不会再实例化该Servlet类,也就是有多个线程在使用这个实例。这样的话,当两个或多个线程同时访问同一个Servlet时,可能会发生多个线程同时访问同一资源的情况,数据可能会变得不一致,所以就很容易造成一系列的一些安全性问题。

    为了保证数据的安全性可以采用下列方式:

    避免使用实例变量、静态变量

    线程安全问题还有些是由实例变量、静态变量造成的,只要在Servlet里面的任何方法里面都不使用实例变量、静态变量,那么该Servlet就是线程安全的。

    对上面的两种种方法进行测试,可以表明用它们都能设计出线程安全的Servlet程序。但是在程序中使用同步来保护要使用的共享的数据,会使系统的性能大大下降。这是因为被同步的代码块在同一时刻只能有一个线程执行它,使得其同时处理客户请求的吞吐量降低,而且很多客户处于阻塞状态。另外为保证主存内容和线程的工作内存中的数据的一致性,要频繁地刷新缓存,这也会大大地影响系统的性能。所以在实际的开发中也应避免或最小化Servlet 中的同步代码;在Serlet中避免使用实例变量是保证Servlet线程安全的最佳选择。从Java 内存模型也可以知道,方法中的临时变量是在栈上分配空间,而且每个线程都有自己私有的栈空间,所以它们不会影响线程的安全。

    同步对共享数据的操作

    使用synchronized 关键字能保证一次只有一个线程可以访问被保护的区段,同步后的代码如下:

    public class XXXServlet extends HttpServlet {  

      ………  

      synchronized (this){

        XXXX

      }  

       ...........

    Servlet的线程安全问题只有在大量的并发访问时才会显现出来,并且很难发现,因此在编写Servlet程序时要特别注意。线程安全问题主要是由实例变量造成的,因此在Servlet中应避免使用实例变量。如果应用程序设计无法避免使用实例变量,那么使用同步来保护要使用的实例变量,但为保证系统的最佳性能,应该同步可用性最小的代码路径。

     

    转载请注明出处:https://www.cnblogs.com/stu-jyj3621
  • 相关阅读:
    基于Freescale的主流芯片HCS08
    BizTalk Server 2010 映射器(Mapper) [ 下篇 ]
    BizTalk Server 2010 使用 WCF Service [ 中篇 ]
    Ext JS 4 Beta 1发布了
    Step by Step WebMatrix网站开发之一:Webmatrix安装
    REST WebService与SOAP WebService的比较
    BizTalk Server 2010 使用 WCF Service [ 上篇 ]
    BizTalk Server 2010 映射器(Mapper) [ 中篇 ]
    BizTalk Server 2010 映射器(Mapper) [ 上篇 ]
    ExtJS 4 Beta 2预览:Ext.Brew包
  • 原文地址:https://www.cnblogs.com/stu-jyj3621/p/14370080.html
Copyright © 2011-2022 走看看