volatile variable can guarantee thread safety it? why?

  1. What volatile is likely?

Turning to the security thread, often comes to a variable --volatile. In the "Java Concurrency in combat," a book is so volatile is defined - "Java language provides a weaker synchronization mechanism, namely volatile variable used to ensure that the update notification variables to other threads." This sentence shows two things: ①volatile variable is a synchronization mechanism; ②volatile to ensure visibility. These two points and we explore "whether volatile variables can guarantee thread safety" are closely related.

  1. volatile variables can be thread-safe sex? why?

What is the synchronization mechanism? In concurrent programming, each process access to public variables must be constrained, this constraint is called synchronization. That is, the synchronization mechanism that is a constraint to shared resources. So the question is: volatile this "weaker synchronization mechanism" is how each process restricts access to shared resources it? The answer lies in "volatile to ensure visibility" in the.

2.1 Visibility

volatile to ensure the visibility of the field: volatile variable used to ensure that the update notification variables to other threads. volatile variables are not cached in the processor register or to other places invisible, thus always return the most recently written values ​​when reading volatile variable.

Visibility and "thread on how to operate the variable (value, assignment, etc.)" relationship:

We must first clear a law: thread all operations on variables (value, assignment, etc.) must be in working memory (each thread independently owned) in progress, but can not directly read and write variables in memory, nor among the working memory mutual visits. For volatile variable, because its special sequential predetermined operation, looks like the general operation of main memory, but in fact is volatile variables follow this law.

Between the main memory and on specific working memory interactive protocol (i.e., how to copy a variable from main memory into the working memory, the details of how to achieve synchronized from the working memory to the main memory, etc.), Java memory model defines the following eight kinds of operations to complete :

lock :( lock), unlock (unlock), read (read), load (load), use (trial), assign (assignment), store (storage), write (write).

volatile these eight kinds of operation has two special limited precisely because of these limits before allowing volatile variables have visibility and can prohibit instruction reordering:

① action must be read before use and load actions, three actions must be consecutive. [Said: Every working memory have to pick up the latest variable volatile main memory prior to use volatile variable]

② assign action must follow after the store and write actions, three actions must be consecutive. [Said: Every working memory changes the value of a volatile variable, the value must be written back to the main memory]

More than two rules to ensure that when each thread can get volatile variable, that variable must be up to date, in fact, it is equivalent to a good number of threads use the same memory, working memory and main memory without points . The operation did not use volatile variables can not be guaranteed every time to get the latest variable value.

2.2 so volatile whether we can guarantee thread safety?

Can not.

After the adoption of 2.1, we have been very clear in a multithreaded environment, one thread modifies a volatile variables, other threads can immediately read the latest value of the variable. However, volatile does not guarantee that each thread is a serial access to the same variable, in the case of a multi-core machine, two or more threads simultaneously make changes to the same shared variable, thread-safety problems still occur. For example: in the case of multi-core machine, i == 0, two threads simultaneously operate i ++, the end result is likely to erroneous results "i == 1".

So: volatile does not guarantee thread safety, because to ensure thread safety must ensure that the operation is in serial form to access shared resources, and volatile can not do this.

2.3 verified by the code "Even with the volatile variables to modify, still there will be thread-safety issues."volatile variable can guarantee thread safety it?  why?

volatile variable can guarantee thread safety it?  why?

Test results: (1) there has been a lot of duplicate numbers; (2) Finally, the output "-1"; == "explanatory variable that is modified but still there was a thread safety problem with using volatile.

Code Analysis:
The problem occurs because (1): The thread race condition exists "to perform after the first check". There may be two threads have execution of the CPU (dual-core machine), they determine to do "if (ticket> 0)" , and while doing "ticket--" operation.
The problem occurs because (2):
① When the ticket == 1, two or more threads simultaneously by the "if (ticket> 0)" determination, and proceeds to execute the judgment box codes;
② then they perform to "Thread.sleep (100);" and sleep;
there is always a thread will grab the first implementation of the right cup, and then execute "ticket--" operation, the latest ticket and told to push the value of each ③ after waking up thread;
④ at this time, those in the other thread determines box and do not judge "if (ticket> 0)" again, but directly to get the latest ticket and do "ticket--" operation.
Even if the thread "ticket--" always do before "if (ticket> 0)" judgment, there will still be thread-safety issues, because they may occur simultaneously ① kind of judgment by the state.

Summary: volatile only to ensure the visibility of the field and prevent reordering (reordered prevent field article did not do in-depth discussion), can not guarantee thread safety.

Guess you like

Origin blog.51cto.com/14528283/2452577