Java Concurrency (c): how to ensure the visibility of shared variables? Java Concurrency (c): how to ensure the visibility of shared variables?

Excerpt: https://www.cnblogs.com/qing-gee/p/11657905.html

Java Concurrency (c): how to ensure the visibility of shared variables?

 

On one , we talked about how to synchronize atomic to ensure shared variables (or more operations or operating a full implementation and execution process will not be interrupted by any factor, or to not execute), this article, we to talk about how to ensure the visibility of shared variables (when multiple threads access the same variable, a thread changes the value of this variable, other threads can immediately see the value changes).

We use synchronous aim is not only do not want a thread in the use of state of the object, another thread in the modified state, so likely to cause confusion; we also want a thread modifies an object state, other threads can see the changes after the state - which involves a new term: memory (can be omitted) visibility.

To learn more visibility, we must first look at Java memory model.

Java memory model (Java Memory Model, referred JMM) describes the Java program variables (variables shared between threads) of access rules, and stored in the variable JVM underlying details → memory variables read from the memory .

You know, all the variables are stored in the main memory, each thread will have its own independent working memory, which holds the thread used variables copies (a copy of main memory variables). See below.

 

 

In other words, thread 1 chenmo shared variables modified in order to be in time to see the thread 2, it must go through two steps:

1, the working memory updated 1 shared variables flushed to main memory.
2, the main memory in the latest update to the value of the shared variable working memory 2.

If that is not shared variable in time be seen by other threads, then what will happen?

public class Wanger {
    private static boolean chenmo = false;

    public static void main(String[] args) {
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                while (!chenmo) {
                }
            }
        });
        thread.start();
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        chenmo = true;

    }

}

This code is intended to: create a child thread in the main thread, and then start it, when the main thread sleeps for 500 milliseconds, the value of the shared variable chenmo modifications to the true time, while the sub-loop thread to stop. But after running this code, the program appears to enter an infinite loop, after the N 500 milliseconds, did not mean to stop.

Why is this so?

Because the main thread of shared variables chenmo changes did not notice the child thread (child thread at run time, the value of a variable copy will chenmo on his work memory of them), when the main thread change the value of the variable after chenmo but not enough time to write them into the main memory, then the child thread do not know at this time the main thread changes chenmo variables, and therefore will loop forever.

In other words, is this: ordinary share variables can not guarantee the visibility, because after the general shared variables are modified, what time is written to main memory is uncertain when the other threads to read, then memory may still be original the old values ​​can not be guaranteed visibility.

Then how to solve this problem?

Use the volatile keyword modification of shared variables chenmo.

Because when volatile variable is accessed by the thread, the thread will be forced to re-read the values ​​of variables from main memory, and when the variable is to modify the thread, the thread will be forced to refresh the nearest value to the main memory of them. In this case, the thread can always see the latest value of the variable at any time.

We modified it to use shared variables chenmo volatile.

private static volatile boolean chenmo = false;

After you run the code again, the program is over in a flash, 500 milliseconds after a very short ah. After the main thread (main method) chenmo modified to true, the value of the variable chenmo immediately written to the main memory of them; the same time, resulting in the working memory child threads cached copy of the variable chenmo fails; when the sub-thread reads the variable chenmo when, found himself cached copy is invalid, it will go to the main memory reads the latest value (from false to true up), so the while loop will stop.

In other words, under certain scenarios, we can safely use the volatile keyword to shared variables. One such scenario is: the state truly independent from other program content Mainland, such as a Boolean status flag (from false to true, then can be converted to false), used to indicate the occurrence of a major one-off events .

As volatile principles and implementation mechanisms herein, this is no longer in-depth launched a (small series that he did not get to know, awkward yet polite smile).

Need to be re-emphasized:

volatile variables can be seen as a "lesser degree of synchronized"; compared with synchronized, volatile variable cost less to run, but it can realize the function is only part of the synchronized (only ensure visibility can not ensure atomicity).

We atomic previous discussed, the increment (i ++) looks like a separate operation, but in fact it is made a "reading - modification - writing" operation sequence consisting of volatile and therefore can not be which provides the necessary characteristics atoms.

In addition to volatile and synchronized, Lock also to ensure visibility, which ensures that only one thread acquires the lock and then synchronize code and to modify variables will be flushed to main memory of them before releasing the lock. More details about Lock, we discuss again later.

Well, the shared variable visibility on the first introduction to this. I hope this article can help you, thank you for reading.

05, finally

Thank you for reading, originality is not easy, like to point a praise, this will be my strongest writing power. If you think the article for your help, but also quite interesting to look at the "silence the king," the public number.

Micro-channel two-dimensional code scanning left side, the author's attention to micro-channel public number: " Silence king "
backstage reply " free video " to get a 500G HD instructional videos, and has been categorized, can be downloaded on demand, speed to!

This article belongs to the author and blog Park total, welcome to reprint, but without the author's consent declared by this section must be retained, and given the original connection in the apparent position of the article page, otherwise the right to pursue legal responsibilities. If you feel that there is help, you can tap the bottom right corner [Recommended].
 
Category: interesting Java

 

On one , we talked about how to synchronize atomic to ensure shared variables (or more operations or operating a full implementation and execution process will not be interrupted by any factor, or to not execute), this article, we to talk about how to ensure the visibility of shared variables (when multiple threads access the same variable, a thread changes the value of this variable, other threads can immediately see the value changes).

We use synchronous aim is not only do not want a thread in the use of state of the object, another thread in the modified state, so likely to cause confusion; we also want a thread modifies an object state, other threads can see the changes after the state - which involves a new term: memory (can be omitted) visibility.

To learn more visibility, we must first look at Java memory model.

Java memory model (Java Memory Model, referred JMM) describes the Java program variables (variables shared between threads) of access rules, and stored in the variable JVM underlying details → memory variables read from the memory .

You know, all the variables are stored in the main memory, each thread will have its own independent working memory, which holds the thread used variables copies (a copy of main memory variables). See below.

 

 

In other words, thread 1 chenmo shared variables modified in order to be in time to see the thread 2, it must go through two steps:

1, the working memory updated 1 shared variables flushed to main memory.
2, the main memory in the latest update to the value of the shared variable working memory 2.

If that is not shared variable in time be seen by other threads, then what will happen?

public class Wanger {
    private static boolean chenmo = false;

    public static void main(String[] args) {
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                while (!chenmo) {
                }
            }
        });
        thread.start();
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        chenmo = true;

    }

}

This code is intended to: create a child thread in the main thread, and then start it, when the main thread sleeps for 500 milliseconds, the value of the shared variable chenmo modifications to the true time, while the sub-loop thread to stop. But after running this code, the program appears to enter an infinite loop, after the N 500 milliseconds, did not mean to stop.

Why is this so?

Because the main thread of shared variables chenmo changes did not notice the child thread (child thread at run time, the value of a variable copy will chenmo on his work memory of them), when the main thread change the value of the variable after chenmo but not enough time to write them into the main memory, then the child thread do not know at this time the main thread changes chenmo variables, and therefore will loop forever.

In other words, is this: ordinary share variables can not guarantee the visibility, because after the general shared variables are modified, what time is written to main memory is uncertain when the other threads to read, then memory may still be original the old values ​​can not be guaranteed visibility.

Then how to solve this problem?

Use the volatile keyword modification of shared variables chenmo.

Because when volatile variable is accessed by the thread, the thread will be forced to re-read the values ​​of variables from main memory, and when the variable is to modify the thread, the thread will be forced to refresh the nearest value to the main memory of them. In this case, the thread can always see the latest value of the variable at any time.

We modified it to use shared variables chenmo volatile.

private static volatile boolean chenmo = false;

After you run the code again, the program is over in a flash, 500 milliseconds after a very short ah. After the main thread (main method) chenmo modified to true, the value of the variable chenmo immediately written to the main memory of them; the same time, resulting in the working memory child threads cached copy of the variable chenmo fails; when the sub-thread reads the variable chenmo when, found himself cached copy is invalid, it will go to the main memory reads the latest value (from false to true up), so the while loop will stop.

In other words, under certain scenarios, we can safely use the volatile keyword to shared variables. One such scenario is: the state truly independent from other program content Mainland, such as a Boolean status flag (from false to true, then can be converted to false), used to indicate the occurrence of a major one-off events .

As volatile principles and implementation mechanisms herein, this is no longer in-depth launched a (small series that he did not get to know, awkward yet polite smile).

Need to be re-emphasized:

volatile variables can be seen as a "lesser degree of synchronized"; compared with synchronized, volatile variable cost less to run, but it can realize the function is only part of the synchronized (only ensure visibility can not ensure atomicity).

We atomic previous discussed, the increment (i ++) looks like a separate operation, but in fact it is made a "reading - modification - writing" operation sequence consisting of volatile and therefore can not be which provides the necessary characteristics atoms.

In addition to volatile and synchronized, Lock also to ensure visibility, which ensures that only one thread acquires the lock and then synchronize code and to modify variables will be flushed to main memory of them before releasing the lock. More details about Lock, we discuss again later.

Well, the shared variable visibility on the first introduction to this. I hope this article can help you, thank you for reading.

05, finally

Thank you for reading, originality is not easy, like to point a praise, this will be my strongest writing power. If you think the article for your help, but also quite interesting to look at the "silence the king," the public number.

Guess you like

Origin www.cnblogs.com/xichji/p/11803034.html
Recommended