Design Pattern in Struts2 -- ThreadLocal pattern continuation

Source: Internet
Author: User

This article is mainly organized by Lu Zhou, "Struts2 technical insider"

  Application scenarios in ThreadLocal Mode

  

After analyzing the source code of ThreadLocal, let's look at the most suitable business scenario of ThreadLocal mode. In a complete "request-response" process, the execution process of the main thread always runs through. What is the impact on the entire process when ThreadLocal is added to read/write of the main thread? Based on the previous source code analysis results and the hierarchical development mode, we can draw the entire process, as shown in Figure 4-1:

As we can see from the figure above, since ThreadLocal operates on copies that are maintained throughout the Thread lifecycle (ThreadLocalMap ), therefore, no matter which layer of the J2EE Program (presentation layer, business logic layer, or persistence layer), as long as within the lifecycle of a Thread, objects stored in ThreadLocalMap are thread-safe (because ThreadLocalMap itself is only affiliated with the current execution thread and is an attribute variable inside the execution thread. We use the shadow part in the figure to represent the storage space of the variable ). This is the core technology used to solve the variable Sharing Problem in the multi-threaded environment. ThreadLocal also makes it widely used in many business scenarios in J2EE development.

  Data sharing or Data Transmission

ThreadLocal mode is widely used in J2EE development because it is very simple and convenient to use Java's own syntax features, especially for cross-layer Resource Sharing. For example, in Spring, there is an example of using ThreadLocal mode to manage database connections or Hibernate sessions.

In some famous forums, there are many discussions about using the ThreadLocal mode for data transmission. In fact, this is a big misunderstanding of the ThreadLocal mode. It should be noted that the ThreadLocal mode solves the problem of data sharing at different development levels in the same thread, rather than passing data at different development levels.

1) the core of the ThreadLocal mode is to implement a shared environment (the static instance of ThreadLocal is encapsulated in the class ). Therefore, when operating ThreadLocal, this shared environment exists everywhere across multiple development layers.

2) the ubiquitous shared environment creates a shared dependency between all development layers, so that all development layers are coupled together and thus cannot be tested independently.

3) data transmission should be explicitly declared through the signature of the interface function, so that the real meaning of the interface can be expressed from the interface declaration. The ThreadLocal mode is inside the implementation, making it impossible to reach an agreement between the interface and the interface.

The de-coupling design concept of Struts2 makes the MVC implementation of Struts2 a natural place to use the ThreadLocal model. In chapter 3, we have introduced some basic concepts. Struts2 introduces the XWork framework, the entire Http request process is split into two stages related to the Web Container and irrelevant to the Web container. The Data Interaction in these two stages is carried out securely through the thread shared copy in ThreadLocal mode. Here, we do not see data transmission, but there is data sharing for the entire execution thread.

Core elements of ThreadLocal Mode

After carefully analyzing the previous section (Figure 4-1), we can find that,To complete the ThreadLocal mode, the most important thing is to create a ThreadLocal instance that can be accessed anywhere (that is, the diamond part in the execution ).This can be achieved through static instance variables of the class. The class used to carry static instance variables is considered as a shared environment. Let's look at an example, as shown in the code list:

1 public class Counter {2 // create a static ThreadLocal variable, and use the get method to change it to an accessible object 3 private static ThreadLocal <Integer> counterContext = new ThreadLocal <Integer> () {4 protected synchronized Integer initialValue () {5 return 10; 6} 7}; 8 // use the static get method to access the value stored in ThreadLocal 9 public static Integer get () {10 return counterContext. get (); 11} 12 // use the static set method to set the variable value to 13 public static void set (Integer value) {14 counterContext. set (value); 15} 16 // encapsulate the business logic. The operation is stored in the variable 17 public static Integer getNextCounter () {18 counterContext. set (counterContext. get () + 1); 19 return counterContext. get (); 20} 21}

In this Counter class, we implement a static ThreadLocal variable and expose the value stored in ThreadLocal through the get method. We also encapsulate a method getNextCounter with business logic, operate the value in ThreadLocal, add it to 1, and return the calculated value.

In this case, the Counter class becomes a data sharing environment, and we also have a key element for implementing the ThreadLocal mode. With it, let's write a simple test, as shown in the following code list:

1 public class ThreadLocalTest extends Thread {2     public void run(){3         for(int i = 0; i < 3; i++){  4             System.out.println("Thread[" + Thread.currentThread().getName() + "],counter=" + Counter.getNextCounter());  5         }  6     }7 }

This is a simple Thread class that cyclically outputs the name of the current thread and the result of getNextCounter. Because the logic in getNextCounter operates on variables in ThreadLocal, no matter how many threads are running at the same time, the returned value is only related to the variable value of the current thread. That is to say, in the same thread, the variable value is continuously added. This can be confirmed by the following test code:

 

 1 public class Test { 2     public static void main(String[] args) { 3         ThreadLocalTest testThread1 = new ThreadLocalTest();   4         ThreadLocalTest testThread2 = new ThreadLocalTest();   5         ThreadLocalTest testThread3 = new ThreadLocalTest();   6         testThread1.start();   7         testThread2.start();   8         testThread3.start(); 9     }10 }

Let's run the above Code and see the output result:

Thread [Thread-2], counter = 11
Thread [Thread-2], counter = 12
Thread [Thread-2], counter = 13
Thread [Thread-0], counter = 11
Thread [Thread-0], counter = 12
Thread [Thread-0], counter = 13
Thread [Thread-1], counter = 11
Thread [Thread-1], counter = 12
Thread [Thread-1], counter = 13

The output above also confirms that the counter's access to the multi-threaded environment is thread-safe. From the analysis of the example, we can once again understand that the ThreadLocal mode is the most suitable use scenario:Share data in different development layers of the same Thread.

In the above example, we can briefly summarize the two main steps for implementing the ThreadLocal mode:
1. Create a class and encapsulate a static ThreadLocal variable in it to make it a shared data environment.

2. Implement a static method (set value and value) to access the static ThreadLocal variable in the class ).

Based on the implementation steps of the ThreadLocal mode, ThreadLocal is easier to use. Anywhere in the thread execution, we can safely obtain the safe variable values in the current thread by accessing the set value and value method of the ThreadLocal variable provided in the shared data class.

These two steps will be mentioned many times later in the implementation of Struts2. As long as the reader can fully understand the basic principle of ThreadLocal processing multi-thread access, then we can have a general understanding of Struts2's data access and data sharing design.

Here, let's look back at the introduction of the ThreadLocal model. What is the significance of ThreadLocal to our programming model?

Conclusion: The ThreadLocal mode can effectively share data at different programming layers.

This is determined by the implementation mechanism of the ThreadLocal mode. Because an important step to implement the ThreadLocal mode is to build a static shared bucket. This allows any object to securely access data at any time.

  Conclusion The ThreadLocal mode can be used to effectively decouple the execution logic from the execution data.

This is the core impact of the ThreadLocal model. In general, the cooperation relationship between Java objects is mainly transmitted through parameters and return values, which is also an important dependency between object collaboration. The ThreadLocal mode completely breaks this dependency and shares data through thread-safe shared objects, effectively avoiding data dependency between programming layers. This has also become the core of XWork event processing system design.

  ---- End ----

 

 

 

 

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.