How to use synchronized and volatile and the difference

Source: Internet
Author: User

Let's take a look at the following example:

 Public classThreadTest { Public Static voidMain (string[] args) {FinalCounter Counter =NewCounter ();  for(inti = 0; i < 1000; i++) {            NewThread (NewRunnable () {@Override Public voidrun () {counter.inc ();        }}). Start ();    } System.out.println (counter); }}
 Public classCounter {Private volatile intCount = 0;  Public voidInc () {Try{Thread.Sleep (3); } Catch(interruptedexception e) {e.printstacktrace (); } Count++; } @Override PublicString toString () {return"[count=" + Count + "]"; }}

The above example is the use of the volatile keyword to decorate a count variable, run the program, the result will be God horse?

The result will not be 1000, or not equal to 1000.

The following is the result of the program running 3 times:

[count=971]

[count=968]

[count=972]

As you can see, the result of the program running is indeterminate, which means that count++ is not an atomic level operation.

The reason is that a variable declared as volatile, if it is related to itself, such as the following declaration method: n=n+1,n++, then the variable declared as volatile does not work, that is, the keyword volatile invalid.

Analysis:

In the Java memory model each thread runs with a line stacks, and the line stacks saves the thread runtime variable value information. When a thread accesses
When an object is valued, the value of the variable that corresponds to the heap memory is found first through the object's reference, and then the concrete value of the heap memory variable is load to the line
Local memory, create a copy of the variable, and then the thread will no longer have any relationship with the object in the heap memory variable value, but directly modify the value of the copy variable.
At some point after the modification (before the thread exits), the value of the thread variable copy is automatically written back to the object in the heap variable. Objects like this in the heap
The value is changed.
This means that 1000 sub-threads are opened in the main function above, and each thread has a copy of the variable, and each thread modifies the variable to only temporarily modify the
Its own copy, and then writes the modified value to the main memory at the end of the thread, so that there is a thread-safety issue. So the result is not equal to 1000.
, which is generally less than 1000.

To change the operation of Count to an atomic level, you can use the keyword synchronized to modify the class counter to:

 Public classCounter { Public Static intCount = 0;  Public synchronized voidInc () {count++; }     Public voidrun () { for(inti = 0; I < 10; i++) {            Try{Inc ();//N=count+1 changed to Inc ()Thread.Sleep (3);//3 milliseconds delay in order to make the running result more immediately}Catch(interruptedexception e) {e.printstacktrace (); } }} @Override PublicString toString () {return"[count=" + Count + "]"; }}

The result of the program running 3 times:

[count=1000]

[count=1000]

[count=1000]

The difference between synchronized and volatile:

Once a shared variable (a member variable of a class, a static member variable of a class) is modified by volatile, then there are two layers of semantics:
1) ensures the visibility of different threads operating on this variable, that is, a thread modifies the value of a variable, which is a new value for other threads
Immediately visible.
2) command reordering is prohibited.
The volatile nature is to tell the JVM that the value of the current variable in the register (working memory) is indeterminate and needs to be read from main memory;
Synchronized is locking the current variable, and other threads are blocked only if the variable is accessible to the front thread.


1.volatile can only be used at variable level;
Synchronized can be used in variables, methods, and class-level


2.volatile can only achieve the change of the visibility of variables, and does not guarantee atomicity;

Synchronized can guarantee the change of the variable visibility and atomicity


3.volatile does not cause the thread to block;
Synchronized may cause a thread to block.


4.volatile tagged variables are not optimized by the compiler;
Synchronized tagged variables can be optimized by the compiler

How to use synchronized and volatile and the difference

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.