java 线程安全总结

来源:转载

一、servlet/JSP 线程安全

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


JSP的中存在的多线程问题:

当客户端第一次请求某一个JSP文件时,服务端把该JSP编译成一个CLASS文件,并创建一个该类的实例,然后创建一个线程处理CLIENT端的请求。如果有多个客户端同时请求该JSP文件,则服务端会创建多个线程。每个客户端请求对应一个线程。以多线程方式执行可大大降低对系统的资源需求,提高系统的并发量及响应时间.对JSP中可能用的的变量说明如下:

实例变量
实例变量是在堆中分配的,并被属于该实例的所有线程共享,所以不是线程安全的.
JSP系统提供的8个类变量
JSP中用到的OUT,REQUEST,RESPONSE,SESSION,CONFIG,PAGE,PAGECONXT是线程安全的,APPLICATION在整个系统内被使用,所以不是线程安全的.


局部变量
局部变量在堆栈中分配,因为每个线程都有它自己的堆栈空间,所以是线程安全的.
静态类
静态类不用被实例化,就可直接使用,也不是线程安全的.
外部资源:
在程序中可能会有多个线程或进程同时操作同一个资源(如:多个线程或进程同时对一个文件进行写操作).此时也要注意同步问题.

常量

常量始终是线程安全的,因为只存在读操作。

构造器:
对构造器的访问(new 操作)是线程安全的,因为每次都新建一个实例,不会访问共享的资源。

Servlet体系结构是建立在Java多线程机制之上的,它的生命周期是由Web容器负责的。当客户端第一次请求某个Servlet时,Servlet容器将会根据web.xml配置文件实例化这个Servlet类。当有新的客户端请求该Servlet时,一般不会再实例化该Servlet类,也就是有多个线程在使用这个实例。Servlet容器会自动使用线程池等技术来支持系统的运行.

这样,当两个或多个线程同时访问同一个Servlet时,可能会发生多个线程同时访问同一资源的情况,数据可能会变得不一致。所以在用Servlet构建的Web应用时如果不注意线程安全的问题,会使所写的Servlet程序有难以发现的错误。

Servlet的线程安全问题主要是由于实例变量使用不当而引起的,可以使用 ThreadLocal类来定义实例变量,也可以使用synchronized 关键字能保证一次只有一个线程可以访问被保护的区段,达到线程安全的目的。

二 、struts 1:
Struts1 Action是单例模式并且必须是线程安全的,因为仅有Action的一个实例来处理所有的请求,因此尽量不要在action里用实例变量。如果要使用,解决方式同 servlet处理线程安全的方法。

三、struts2:

Struts 2 Action对象为每一个请求产生一个实例,action中会加上一个注解scope("prototype")
因此没有线程安全问题 。




分享给朋友:
您可能感兴趣的文章:
随机阅读: