`

线程安全,有状态,无状态的对象

阅读更多

进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位.
线程是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位.
另外,进程在执行过程中拥有独立的内存单元,而多个线程共享内存,从而极大地提高了程序的运行效率。
进程有独立的地址空间


进程有单独的地址空间,包括文本区域(text region)、数据区域(data region)和堆栈(stack region)。
文本区域存储处理器执行的代码;
数据区域存储变量和进程执行期间使用的动态分配的内存;
堆栈区域存储着活动过程调用的指令和本地变量。


线程有自己的堆栈和局部变量,但线程之间没有单独的地址空间
一个线程包含以下内容。

•一个指向当前被执行指令的指令指针;
•一个栈;
•一个寄存器值的集合,定义了一部分描述正在执行线程的处理器状态的值;
•一个私有的数据区。

线程安全 


如果你的代码所在的进程中有多个线程在同时运行,而这些线程可能会同时运行这段代码。如果每次运行结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的是一样的,就是线程安全的。   或者说:一个类或者程序所提供的接口对于线程来说是原子操作或者多个线程之间的切换不会导致该接口的执行结果存在二义性,也就是说我们不用考虑同步的问题。   线程安全问题都是由全局变量及静态变量引起的。  
若每个线程中对全局变量、静态变量只有读操作,而无写操作,一般来说,这个全局变量是线程安全的;若有多个线程同时执行写操作,一般都需要考虑线程同步,否则就可能影响线程安全。

 

关于线程安全:

 

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

 

2)每次调用方法前都新建一个实例是线程安全的,因为不会访问共享的资源。

 

3)局部变量是线程安全的。因为每执行一个方法,都会在独立的空间创建局部变量,它不是共享的资源。局部变量包括方法的参数变量和方法内变量。 


有状态和无状态对象

有状态就是有数据存储功能。有状态对象(Stateful Bean),就是有实例变量的对象  ,可以保存数据,是非线程安全的。在不同方法调用间不保留任何状态。

无状态就是一次操作,不能保存数据。无状态对象(Stateless Bean),就是没有实例变量的对象  .不能保存数据,是不变类,是线程安全的。

有状态对象:

Java代码  收藏代码
  1.  public   class  StatefulBean {     
  2.      
  3.      public   int  state;     
  4.    
  5.      public   int  getState() {     
  6.          return  state;     
  7.     }     
  8.     
  9.      public   void  setState( int  state) {     
  10.          this .state = state;     
  11.     }     
  12.     
  13.      public  User getUser() {     
  14.          return  user;     
  15.     }     
  16.     
  17.      public   void  setUser(User user) {     
  18.          this .user = user;     
  19.    }     
  20. }     

 无状态对象

Java代码  收藏代码
  1. public   class  StatefulBean {     
  2.     
  3.    // 虽然有userDao 属性,但userDao 是没有状态信息的,是Stateless Bean。  
  4.     public   UserDao  userDao  ;     
  5.   
  6.     public   int  getState() {     
  7.         return  state;     
  8.    }     
  9.    
  10.     public   void  setState( int  state) {     
  11.         this .state = state;     
  12.    }     
  13.    
  14.     public  User getUser() {     
  15.         return  user;     
  16.    }     
  17.    
  18.     public   void  setUser(User user) {     
  19.         this .user = user;     
  20.   }     
  21.      

 单例类可以是有状态的(stateful),也可以是无状态的。无状态的单例模式,是线程安全的。有状态的单例模式,是非线程安全的。

 

 

Spring中的有状态(Stateful)和无状态(Stateless)   

1.通过上面的分析,相信大家已经对有状态和无状态有了一定的理解。无状态的Bean适合用不变模式,技术就是单例模式,这样可以共享实例,提高性能。有状态的Bean,多线程环境下不安全,那么适合用Prototype原型模式。Prototype: 每次对bean的请求都会创建一个新的bean实例。

2.默认情况下,从Spring bean工厂所取得的实例为singleton(scope属性为singleton),容器只存在一个共享的bean实例。

3.理解了两者的关系,那么scope选择的原则就很容易了:有状态的bean都使用prototype作用域,而对无状态的bean则应该使用singleton作用域。

4.如Service层、Dao层用默认singleton就行,虽然Service类也有dao这样的属性,但dao这些类都是没有状态信息的,也就是 相当于不变(immutable)类,所以不影响。Struts2中的Action因为会有User、BizEntity这样的实例对象,是有状态信息 的,在多线程环境下是不安全的,所以Struts2默认的实现是Prototype模式。在Spring中,Struts2的Action中,scope 要配成prototype作用域。

 

 

 

Struts中的线程安全

 

1.Struts1也是基于单例模式实现,也就是只有一个Action实例供多线程使用。默认的模式是前台页面数据通过actionForm传入,在 action中的excute方法接收,这样action是无状态的,所以一般情况下Strunts1是线程安全的。如果Action中用了实例变量,那 么就变成有状态了,同样是非线程安全的。

 

 

2.Struts2默认的实现是Prototype模式。也就是每个请求都新生成一个Action实例,所以不存在线程安全问题。需要注意的是,如果由Spring管理action的生命周期, scope要配成prototype作用域。

 

总结:   
Stateless无状态用单例Singleton模式,Stateful有状态就用原型Prototype模式。  
Stateful 有状态是多线程编码的天敌,所以在开发中尽量用Stateless无状态,无状态是不变(immutable)模式的应用,有很多优点:不用管线程和同步的问题  ,如果值是不可变的,程序不用担心多个线程改变共享状态,所以可以避免线程竞争的bugs. 因为没有竞争,就不用用locks等机制,所以无状态的不变机制,也可以避免产生死锁现象。

原文出处:

http://blog.csdn.net/showwair/article/details/7672443

分享到:
评论

相关推荐

    Java线程:线程状态的转换

    线程状态之间的转换是多线程编程的核心概念之一,理解这些转换有助于我们更好地设计和调试并发程序。 1. **新状态到可运行状态**:当线程对象的`start()`方法被调用时,线程从新状态进入可运行状态。 2. **可运行...

    Java线程状态流转图

    Java线程状态流转图知识点总结 Java线程状态流转图是一种用于描述Java线程生命周期中不同的状态和状态转换的图形表示方式。该图形展示了Java线程从创建到终止的整个生命周期,并详细介绍了每种状态的特点和转换...

    java线程状态转换图

    Java 线程状态转换图 Java 线程状态转换图是 Java 编程中非常重要的一个概念,它描述了线程在不同的状态之间的转换关系。了解线程状态转换图对 Java 编程的理解和应用非常重要。本文将详细介绍 Java 线程状态转换图...

    MFC的状态 模块状态、进程状态、线程状态。

    - **线程状态维护**:线程状态的指针指向当前运行模块的状态或前一运行模块的状态,这有助于在多模块环境中管理不同的状态。 综上所述,MFC的状态管理机制提供了一套完整的框架来处理不同层次的状态信息,包括模块...

    构建线程安全应用程序

    首先,线程安全性关注的是对象在操作过程中的状态完整性。在单线程环境下,对象的操作不会被打断,状态变化是连续的,不会出现中间状态。然而,在多线程环境下,一个操作的执行可能会被另一个线程的操作所干扰,导致...

    线程和内核对象的同步

    线程在获取互斥对象时,如果已被其他线程持有,则会进入等待状态,直到该对象被释放。 7. **线程同步对象速查表**和**其他的线程同步函数**:这部分提供了快速参考,总结了各种内核对象的特性,并介绍了一些额外的...

    java线程安全总结.doc

    1. **无状态对象**:对象的状态不会被任何线程修改,因此它们天生线程安全。 2. **线程不安全对象**:对象的状态可以被多个线程同时修改,容易引发数据不一致。 3. **线程安全对象**:对象提供了保证线程安全的方法...

    局部变量线程安全测试

    线程安全通常指的是当多个线程访问一个对象时,如果对象的状态始终保持一致,那么我们就说这个对象是线程安全的。这里的“状态”包括对象的数据成员和方法的行为。 标题“局部变量线程安全测试”提示我们,我们将...

    vc中获取一个线程的状态及返回值

    - 可以使用`GetThreadContext()`,`GetThreadTimes()`,或`QueryThreadCycleTime()`等API查询线程状态。 4. **线程同步**: - 为了确保线程安全,通常需要使用同步机制,如互斥量(`Mutex`)、信号量(`Semaphore...

    Action是否线程安全

    - **无状态对象**:设计无状态的`Action`,即对象不包含任何可变状态,可以使对象天然线程安全。 - **同步方法**:对于修改状态的方法,使用`synchronized`关键字确保同一时间只有一个线程可以执行。 - **使用并发...

    当析构函数遇到多线程── C++ 中线程安全的对象回调 PDF

    ### 当析构函数遇到多线程——C++中线程安全的对象回调 #### 1. 多线程下的对象生命期管理 C++作为一种需要程序员手动管理对象生命周期的语言,在多线程环境中尤其需要谨慎处理对象的创建和销毁过程。由于多线程...

    设计滚动字演示线程状态及改变方法

    - **线程状态**:线程有五种基本状态:新建、就绪、运行、阻塞和死亡。理解这些状态对于正确控制线程至关重要。 2. **滚动文字实现**: - **文本显示**:Java提供了`java.awt`和`javax.swing`包,用于创建图形...

    多线程事件对象通讯

    事件对象有三种状态:信号状态(Signaled State)和非信号状态(Non-Signaled State),以及自动重置和手动重置两种类型。当事件对象处于信号状态时,等待该事件的线程可以被唤醒;当处于非信号状态时,所有尝试等待...

    Delphi多线程的安全问题分析及解决

    与临界区和互斥对象不同,信号量允许多个线程同时访问资源,但数量有限制。 4. **异常处理**:为了确保线程在异常情况下的安全,可以采用异常处理机制来捕获和处理异常,避免程序因未处理的异常而崩溃。 5. **...

    MFC属于模块-线程状态的部分.DOC

    线程状态则与当前执行代码的上下文相关,每个线程都有自己的线程状态,包括如消息队列、当前选中的DC(设备上下文)等信息。`_AFX_THREAD_STATE`类用于描述线程状态,而`AFX_MODULE_THREAD_STATE`则是线程状态与模块...

    Java源码查看线程的运行状态.rar

    本文将深入探讨Java源码中查看线程状态的方法,并通过一个经典的实例来阐述这一过程。 线程在Java中由`java.lang.Thread`类表示,其生命周期包括以下几种状态: 1. **新建**(New):当使用`new Thread()`创建了一...

    Java多线程(二)、线程的生命周期和状态控制

    #### 二、线程状态的控制 为了更好地管理线程的状态,Java提供了一系列的方法来帮助开发者控制线程的状态,主要包括: 1. **`void destroy()`**: - 已过时。最初用于销毁线程,但不进行任何清理工作。可能导致...

    Java并发中的线程安全性

    5. **无状态(Stateless)**:由于对象不保存任何状态,因此总是线程安全的。 #### 4. 设计线程安全类的原则 为了设计出线程安全的类,可以遵循以下原则: 1. **避免使用共享可变状态**:通过减少类内部共享的...

    线程安全Vector

    虽然 `Vector` 的方法都是同步的,但这并不意味着在所有情况下都可以无脑使用 `Vector` 而不用担心线程安全问题。例如,在多线程环境中,如果不恰当地使用 `Vector`,依然可能遇到线程安全问题。 **示例:** ```...

Global site tag (gtag.js) - Google Analytics