Java multi-thread memory visibility

Source: Internet
Author: User
Tags flushes visibility volatile

1. What is the Java memory model

The Java memory model describes how threads can interact with memory. In particular, there is a Main memory area in the JVM (either memory or Java HEAP memory) that is shared with all threads, and each thread has its own working memory (working memory), and the working RAM holds copies of certain variables The operation of a thread on all variables does not occur in the main memory area, but instead occurs in the working RAM, and the threads are not directly accessible to each other, and the variables are passed in the program and are dependent on main memory to complete.


The Java memory model is abstracted as follows:

650) this.width=650; "Src=" http://cdn3.infoqstatic.com/statics_s1_20151020-0055-2/resource/articles/ Java-memory-model-1/zh/resources/11.png "style=" border:0px;margin:0px 10px 10px 0px;padding:0px; "/>

From the point of view, if you want to communicate between thread A and thread B, you have to go through the following 2 steps:

1. Thread A flushes the updated shared variables in local memory A to the main memory.
2. Thread B goes to main memory to read shared variables that have been updated before thread A.
These two steps are described below:

650) this.width=650; "Src=" http://cdn3.infoqstatic.com/statics_s1_20151020-0055-2/resource/articles/ Java-memory-model-1/zh/resources/22.png "style=" border:0px;margin:0px 10px 10px 0px;padding:0px;/>

Overall, these two steps are essentially thread a sending a message to thread B, and the communication process must go through main memory. JMM provides a memory visibility guarantee for Java programmers by controlling the interaction between main memory and the local memory of each thread.

2. What is memory visibility?

If thread A modifies the shared variable x , but thread a does not immediately flash the updated value into main memory , and thread B reads the value of the shared variable x from the main memory, so the value of x is the original value, then we say that for thread B, The change to shared variable x is not visible to thread B. What happens if a shared update is not visible? Take a look at the following example:

[Java] view plain copy

  1. class MyThread implements Runnable {

  2. int num = 1000000;

  3. Public void Run () {

  4. if (Thread.CurrentThread (). GetName (). Equals ("T1")) {

  5. Increment ();

  6. } Else {

  7. Decrement ();

  8. }

  9. }

  10. Public void increment () {

  11. for (int i = 0; i < 10000; i++) {

  12. num++;

  13. }

  14. }

  15. Public void Decrement () {

  16. for (int i = 0; i < 10000; i++) {

  17. num--;

  18. }

  19. }

  20. }

  21. Public class Test {

  22. Public Static void Main (string[] args) {

  23. MyThread thread = new MyThread ();

  24. Thread A = new thread (thread, "T1");

  25. Thread B = new thread (thread, "T2");

  26. A.start ();

  27. B.start ();

  28. Try {

  29. A.join ();

  30. B.join ();

  31. } catch (Exception e) {

  32. E.printstacktrace ();

  33. }

  34. System.out.println (Thread.num);

  35. }

  36. }


as can be seen from the above code, there are two threads, one of which performs 1000 plus 1 operations on NUM, and the other thread executes 1000 plays minus 1, which is supposed to be the last num value is constant, but when you run it, the value of NUM may not be the initial value. So why is there such a problem? This is caused by memory not being visible.

650) this.width=650; "src=" http://img.blog.csdn.net/20150814213739108 "alt=" here to write a picture description "/>

From what we can see, when thread 1 adds one to the NUM value, the CPU stops the execution of thread 1, and executes thread 2, thread 2 first obtains the value of num from main memory, then minus one and finally updates the value to main memory, when the CPU terminates the execution of thread 2. Instead of continuing with thread 1, thread 1 brushes the latest value into memory, so the main memory result becomes 1000001.

Through the above analysis, we learned that: memory is not visible because the value of the shared variable is not updated in the main memory in time, why is not updated in a timely manner? Because the addition of one (or minus one) operation is not atomic (the last step in the example is interrupted). So how do you ensure that the operation is atomic? Here we introduce the Synchronized keyword.

3. Synchronized key Words

Synchronized is used to lock objects and methods or blocks of code, and when it locks a method or a block of code, at most one thread at a time executes the code. When two concurrent threads access the same object in the same lock synchronization code block, only one thread can be executed within a single time. The other thread must wait for the current thread to finish executing the block before it can execute the code block. However, when a thread accesses one of the lock code blocks of object, another thread can still access the non-locking code block in the object.

JMM two provisions on synchronized:

1. Before line threads unlocked, the latest value of shared variable must be flushed to main memory
2. When the thread Cheng, the value of shared variables in the working memory is emptied, so the most recent values need to be reread from main memory when using shared variables.

In this way, changes to shared variables before line threads unlocked are visible to other threads the next time the lock is added.

So, in order to ensure that NUM's modification at some point is atomic, we can add synchronized to the following two methods . If you zhi ' DUI


[Java] view plain copy

  1. Public synchronized void increment () {

  2. for (int i = 0; i < 10000; i++) {

  3. num++;

  4. }

  5. }

  6. Public synchronized void Decrement () {

  7. for (int i = 0; i < 10000; i++) {

  8. num--;

  9. }

  10. }

Because the essence of synchronized is a lock, we can also realize the memory visibility through the real sense of locking and unlocking. The code is as follows:


[Java] view plain copy

  1. class MyThread implements Runnable {

  2. int num = 1000000;

  3. Lock lock = new reentrantlock ();

  4. Public void Run () {

  5. if (Thread.CurrentThread (). GetName (). Equals ("T1")) {

  6. Increment ();

  7. } Else {

  8. Decrement ();

  9. }

  10. }

  11. Public void increment () {

  12. for (int i = 0; i < 10000; i++) {

  13. Lock.lock ();

  14. num++;

  15. Lock.unlock ();

  16. }

  17. }

  18. Public void Decrement () {

  19. for (int i = 0; i < 10000; i++) {

  20. Lock.lock ();

  21. num--;

  22. Lock.unlock ();

  23. }

  24. }

  25. }

You might ask: can we add volatile to the memory visibility in front of num? The answer is no, the volatile implementation of shared variable memory visibility has a condition that operations on shared variables must be atomic. such as num = 10; This operation is atomic, but num++ or num--is made up of 3 steps and does not have atomicity, so it is not possible.

Reference:

HTTP://WWW.INFOQ.COM/CN/ARTICLES/JAVA-MEMORY-MODEL-1 (the first part of this article is mainly from this article)

http://blog.csdn.net/xingjiarong/article/details/47603813 (the second part of this article is mainly from this article, the code has been modified)
Http://baike.baidu.com/item/synchronized

http://www.imooc.com/learn/352


Java multi-thread memory visibility

Related Article

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.