In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-19 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Internet Technology >
Share
Shulou(Shulou.com)06/01 Report--
This article focuses on "Java concurrent programming in the mainstream framework how to apply", interested friends may wish to take a look. The method introduced in this paper is simple, fast and practical. Let's let the editor take you to learn how to apply Java concurrent programming in various mainstream frameworks.
Java memory model
The JVM specification defines the Java memory model to shield the memory access differences of various operating systems, virtual machine implementers and hardware, so as to ensure that Java programs can achieve consistent memory access on all operating systems and platforms.
Working memory and main memory
The Java memory model stipulates that all variables are stored in main memory, each thread has its own independent working memory, and the working memory holds a copy of the main memory copy of the variables used by the thread. Threads operate on these variables in their own working memory, and cannot directly manipulate variables or copies of variables stored in main memory and other working memory. The variable transfer between threads needs to be done through the main memory, and the relationship between the three is shown in the following figure.
Java memory Operation Protocol
The Java memory model defines eight operations to complete variable access to main memory and working memory, as follows.
Read: transfers the value of a variable from main memory to the thread's working memory for use by subsequent load actions. Load: load the variable values read from the main memory into the variable copy of the working memory. Use: passes the value of a variable in working memory to the Java virtual machine execution engine. Assign: assigns values of variables received from the execution engine to variables in working memory. Store: transfers the value of a variable in working memory to main memory for subsequent write operations. Write: the variable values passed from the working memory are put into the main memory. Lock: identifies a variable in main memory as the exclusive state of a thread. Unlock: release a locked variable in main memory so that the released variable can be locked by other threads.
Three characteristics of memory model 1. Atomicity
This concept is roughly consistent with atomicity in transactions, indicating that the operation is indivisible, uninterruptible, and either executed at all or not at all. The atomic operations directly guaranteed by the Java memory model include read, load, use, assign, store, write, lock and unlock.
2. Visibility
Visibility means that when one thread modifies the value of a shared variable, other threads are immediately aware of the change. The Java memory model realizes visibility by synchronizing the new value back to the main memory after the variable is modified, and refreshing the variable value from the main memory before the variable is read, which depends on the main memory as the transmission medium, no matter the ordinary variable or the volatile variable. The difference between the ordinary variable and the volatile variable is that the special rule of volatile ensures that the new value can be synchronized to the main memory immediately and refreshed from the main memory immediately before each use. Therefore, it can be said that volatile guarantees the visibility of variables in multithreaded operations, while ordinary variables do not. In addition to volatile, synchronized also provides visibility, which is obtained by the rule that the variable must be synchronized back into main memory (performing store, write operations) before performing a unlock operation on the variable.
3. Order
In a single-threaded environment, the program executes in an "orderly" manner, that is, serial semantics within the thread. However, in the multithreaded environment, the correctness of concurrent execution will be affected because of instruction rearrangement. The use of volatile and synchronized keywords in Java can ensure the order of multithreaded execution. Volatile disables reordering of memory by adding a memory barrier instruction. By locking, synchronized ensures that only one thread executes synchronized code at a time.
Application of volatile
In the code that opens NioEventLoop, there is an int type field ioRatio decorated with volatile that controls the proportion of IO operations and other tasks, as shown below.
Private volatile int ioRatio = 50
Why is it decorated with volatile here? We first explain the volatile keyword, and then analyze it with the code of Netty.
The keyword volatile is the lightest synchronization mechanism provided by Java, and the Java memory model defines some special access rules for volatile. Let's take a look at its rules. When a variable is modified by volatile, it will have the following two characteristics.
Thread visibility: when a thread modifies a variable decorated by volatile, other threads can immediately see the latest changes, regardless of whether they are locked or not, while normal variables cannot. Prohibit instruction reordering optimization: ordinary variables only ensure that the correct results can be obtained in all places that depend on the assignment results during the execution of the method, but can not guarantee that the order of variable assignment operations is consistent with the execution order of the program code. Give a simple example to illustrate the instruction reordering optimization problem, the code is as follows.
Public class ThreadStopExample {private static boolean stop; public static void main (String [] args) throws InterruptedException {Thread workThread = new Thread (new Runnable () {public void run () {int I = 0; while (! stop) {iride; try {TimeUnit.SECONDS.sleep (1) } catch (InterruptedException e) {e.printStackTrace ();}); workThread.start (); TimeUnit.SECONDS.sleep (3); stop = true;}}
We expect the program to stop after 3 seconds, but in fact it will continue to execute because the virtual machine reorders and optimizes the code, and the optimized instructions are as follows.
If (! stop) While (true)
When the workThread thread executes the reordered code, it cannot find that the variable stop has been modified by another thread, so it cannot stop running. To solve this problem, simply add the volatile modifier before stop. Volatile solves the following two problems. First, the changes made by the main thread to the stop are visible in the workThread thread, which means that the workThread thread immediately sees changes to the stop variable made by other threads. Second, instruction reordering is prohibited to prevent the confusion of concurrent access logic caused by reordering.
Some people think that using volatile can replace traditional locks and improve concurrency performance, which is wrong. Volatile only solves the visibility problem, but it does not guarantee mutual exclusion, that is, when multiple threads modify a variable concurrently, there will still be multithreading problems. Therefore, traditional locks cannot be completely replaced by volatile. According to experience, the most suitable scenario for volatile is "one thread writes, other threads read". If there are multiple threads writing concurrently, you still need to use locks or thread-safe containers or atomic variables instead. Let's continue to analyze the source code of Netty. It is mentioned above that ioRatio is defined as volatile. Let's take a look at why the code is defined this way.
Final long ioTime = System.nanoTime ()-ioStartTime; runAllTasks (ioTime * (ioRatio) / ioRatio)
Through code analysis, we found that in the NioEventLoop thread, ioRatio has not been modified, it is a read-only operation. Since it hasn't been modified, why define it as volatile? Continuing to look at the code, we find that NioEventLoop provides a public way to reset the IO execution time ratio.
Public void setIoRatio (int ioRatio) {if (ioRatio 100) {throw new IllegalArgumentException ("ioRatio:" + ioRatio + "(expected: 0 < ioRatio)
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.