Mastering stateful and stateless (Stateful vs Stateless)

I believe that many people still don’t understand the concept of stateful and stateless, so let’s talk about stateful and stateless today.

basic concept:

Stateful means having data storage capabilities. Stateful objects (Stateful Beans) are objects with instance variables that can store data and are not thread-safe. No state is preserved between method calls.

Stateless is an operation that cannot save data. Stateless objects (Stateless Beans) are objects that do not have instance variables, cannot save data, are immutable classes, and are thread-safe.

The code is better to understand:

/** 
 * 有状态bean,有state,user等属性,并且user有存偖功能,是可变的。 
 *  
 * @author Peter Wei 
 *  
 */  
public class StatefulBean {  

    public int state;  
    // 由于多线程环境下,user是引用对象,是非线程安全的  
    public User user;  

    public int getState() {  
        return state;  
    }  

    public void setState(int state) {  
        this.state = state;  
    }  

    public User getUser() {  
        return user;  
    }  

    public void setUser(User user) {  
        this.user = user;  
    }  
}  

/** 
 * 无状态bean,不能存偖数据。因为没有任何属性,所以是不可变的。只有一系统的方法操作。 
 *  
 * @author Peter Wei 
 *  
 */  
public class StatelessBeanService {  

    // 虽然有billDao属性,但billDao是没有状态信息的,是Stateless Bean.  
    BillDao billDao;  

    public BillDao getBillDao() {  
        return billDao;  
    }  

    public void setBillDao(BillDao billDao) {  
        this.billDao = billDao;  
    }  

    public List<User> findUser(String Id) {  
return null;  
    }  
} 

Stateful and stateless in singleton pattern:

A singleton class can be stateful, and a stateful singleton object is generally a mutable singleton object. Stateful, mutable singleton objects are often used as state repositories. For example, a singleton object TaskCache (singleton in Spring) can hold a property of type AtomicLong, which is used to provide a system with a numerically unique serial number as an ID generator for task communication management. At the same time, a singleton class can also hold an aggregate, allowing multiple states to be stored, such as the ExpiringMap cached task list in the example.

Code example:

import java.util.concurrent.atomic.AtomicLong;

import org.apache.mina.util.ExpiringMap;

/**
 * Description: 内存中缓存的实时控制端任务列表.示例有状态的单例类
 * 
 * @author Peter Wei
 * @version 1.0 Dec 2, 2008
 */
public class TaskCache {

    // 请求超时
    private short requestTimeout;

    // 这个缓存Map是线程安全,并且有定时超时功能
    private ExpiringMap<String, Object> tasksMap = new ExpiringMap<String, Object>();

    // 线程安全的原子类,示例有状态的单例类
    private static AtomicLong seqNo = new AtomicLong(1);

    // 示例有状态的单例类
    public Long nextSeqNo() {
        return seqNo.getAndIncrement();
    }

    public void setRequestTimeout(short requestTimeout) {
        this.requestTimeout = requestTimeout;
    }

    // 启动过期检测
    public void startExpiring() {
        tasksMap.getExpirer().setTimeToLive(requestTimeout);
        tasksMap.getExpirer().startExpiringIfNotStarted();
    }

    // 停止过期检测
    public void stopExpiring() {
        tasksMap.getExpirer().stopExpiring();
    }

    // 取任务列表.
    public Object getTasks(String key) {
        return tasksMap.get(key);
    }

    // 去除任务列表.
    public Object removeTasks(String key) {
        return tasksMap.remove(key);
    }

    // 添加任务列表.
    public void addTasks(String key, Object value) {
        tasksMap.put(key, value);
    }
}

Singleton classes can also be stateless, and are only used as objects that provide utility functions. Since it is to provide utility functions, there is no need to create multiple instances, so the singleton pattern is suitable. Ordinary singleton classes are stateless, so there is no example here. A stateless singleton class is also known as an Immutable singleton class. For invariant mode, please refer to http://www.iteeye.com/topic/959751

Stateful vs Stateless in EJB:

  1. Each user of the Stateful session bean has its own instance, so the operations of the two on the stateful session bean will not affect the other. Also note: If you need to operate an instance of a user later, you must cache the bean's Stub object on the client side (JSP usually uses Session cache), so that in each subsequent call, the container knows to provide the same bean instance.

  2. The Stateless Session Bean is not responsible for recording the user state. Once the Stateless Session Bean is instantiated, it is added to the session pool and can be shared by all users. If it has its own properties (variables), then those variables are affected by all users who call it.

  3. In terms of memory, compared with Stateless Session Bean, Stateful Session Bean will consume more memory of J2EE Server. However, the advantage of Stateful Session Bean is that it can maintain the user's state.

Stateful and Stateless in Spring

  1. Through the above analysis, I believe that everyone has a certain understanding of state and statelessness. **Stateless beans are suitable for invariant mode, and the technology is singleton mode, which can share instances and improve performance. Stateful Beans are not safe in a multi-threaded environment, so Prototype prototype mode is suitable. **Prototype: Each request to the bean creates a new bean instance.

  2. By default, the instance obtained from the Spring bean factory is singleton (scope attribute is singleton), and there is only one shared bean instance in the container.

  3. Understand the relationship between the two, then the principle of scope selection is easy: stateful beans should use prototype scope, while stateless beans should use singleton scope.

  4. For example, the Service layer and the Dao layer can use the default singleton. Although the Service class also has attributes such as dao, these dao classes have no state information, that is, they are equivalent to immutable classes, so they do not affect them. Action in Struts2 has state information because there are instance objects such as User and BizEntity, and it is not safe in a multi-threaded environment, so the default implementation of Struts2 is Prototype mode. In Spring, in the Action of Struts2, the scope should be configured as the prototype scope.

Stateful and Stateless in Servlet, Struts:

The servlet architecture is built on the Java multi-threading mechanism, and its life cycle is taken care of by the Web container. Only one instance of a Servlet class exists in the Application, that is, multiple threads are using this instance. This is an application of the singleton pattern. Stateless singletons are thread-safe, but if we use instance variables in servlets, it becomes stateful and thread-safe. Such as the following usage is not safe, because user, out are stateful information.

/** 
 1. 非线程安全的Servlet。 
 2. @author Peter Wei 
 3. 
 */  
public class UnSafeServlet HttpServlet{  

    User user;  
    PrintWriter out;  

    public void doGet (HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException{  
        //do something...  
    }  
}  

Out, Request, Response, Session, Config, Page, PageContext are thread-safe, and Application is used throughout the system, so it is not thread-safe.

Struts1 is also implemented based on the singleton mode, that is, only one Action instance is used by multiple threads. The default mode is that the front page data is passed in through the actionForm and received by the execute method in the action, so that the action is stateless, so under normal circumstances Strunts1 is thread-safe. If an instance variable is used in the Action, it becomes stateful, which is also not thread-safe. Something like the following is thread unsafe.

/**
 * 非线程安全的Struts1示例
 * 
 * @author Peter Wei
 * 
 */
public class UnSafeAction1 extends Action {

    // 因为Struts1是单例实现,有状态情况下,对象引用是非线程安全的
    User user;

    public void execute() {
        // do something...
    }

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }
}  

The default implementation of Struts2 is Prototype mode. That is, each request generates a new Action instance, so there is no thread safety problem. It should be noted that if Spring manages the life cycle of the action, the scope should be configured as the prototype scope.

How to solve the thread safety problem of Servlet and Struts1, when we can better understand the principle of state and state, it is easy to draw the conclusion: don't use stateful beans, that is, don't use instance variables. If used, use the prototype mode. From the Struts1 user guide: Only Use Local Variables - The most important principle that aids in thread-safe coding is to use only local variables, not instance variables , in your Action class.

Summarize:

1. Stateless uses the Singleton mode for stateless, and Prototype mode for Stateful.

2. Stateful state is the natural enemy of multi-threaded coding, so try to use Stateless in development. Stateless is an application of immutable mode. Changed, the program does not have to worry about multiple threads changing the shared state, so it can avoid thread contention bugs. Because there is no competition, there is no need for mechanisms such as locks, so the stateless immutability mechanism can also avoid deadlocks.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325568051&siteId=291194637