Synchronized lock class method, volatile keyword, and other

Source: Internet
Author: User

Http://www.cnblogs.com/xrq730/p/4853578.html

Synchronized can also be applied to static methods, and if so, it represents the class lock that corresponds to the current. java file . Take a look at the example and note that PRINTC () is not a static method:

PublicClassthreaddomain25{PublicSynchronizedStaticvoidPrintA () {Try{System.out.println ("Thread name is:" + thread.currentthread (). GetName () + "in" + system.currenttimemillis () + "Enter Printa () method"); Thread.Sleep (3000); SYSTEM.OUT.PRINTLN ("Thread name is:" + thread.currentthread (). GetName () + "in" + system.currenttimemillis () + "Leave Printa () method"); }Catch(Interruptedexception e) {E.printstacktrace ();} }PublicSynchronizedStaticvoid Printb () {System.out.println ("Thread Name:" + Thread.CurrentThread (). GetName () + "in" + System.currenttimemillis () + "Enter Printb () method" ); SYSTEM.OUT.PRINTLN ("Thread name is:" + thread.currentthread (). GetName () + "in" + system.currenttimemillis () + "Leave Printb () method" Span style= "color: #000000;" >); } public synchronized  Void Printc () {System.out.println ("Thread Name:" + Thread.CurrentThread (). GetName () + "in" + System.currenttimemillis () + "Enter PRINTC () method" );  System.out.println ( "thread Name:" + thread.currentthread (). GetName () + "in" + system.currenttimemillis () + "Leave Printc () method" ); }}

Write three threads to invoke these three methods individually:

Extends thread{    void run () {Threaddomain25.printa ();}}
Extends thread{    void run () {THREADDOMAIN25.PRINTB ();}}
Extends thread{    privatepublicthis.td =void run () {TD.PRINTC ();}}    

Write a main function to start the three threads:

void Main (string[] args) {New New new     Mythread25_2 (TD); Mt0.start (); Mt1.start (); Mt2.start ();}     

Look at the results of the operation:

The thread name is: thread-0 in 1443857019710 Enter Printa () method thread name is: thread-2 in 1443857019710 enter PRINTC () method thread name is: thread-  2 in 1443857019710 leave the PRINTC () method thread name is: thread-0 in 1443857022710 leave Printa () method thread name is: thread-  1 in 1443857022710 Enter the PRINTB () method thread name is: thread-1 leaves the PRINTB () method in 1443857022710

From the result of the run, the call to the PRINTC () method and the call to the Printa () method, the Printb () method are asynchronous, which shows that the static synchronous method and the non-static synchronization method hold different locks, the former is a class lock, and the latter is an object lock .

The so-called class lock, to give a further concrete example. If a class has a static synchronization method a,new out two classes of instance B and instance C, thread D holds instance B, thread E holds instance C, and as long as thread D calls the A method, then thread E calls the A method must wait for thread D to finish executing the A method, although two threads hold different objects.

volatile keyword

Give an example straight ahead:

PublicClass MYTHREAD28Extendsthread{PrivateBoolean isrunning =Truepublic booleanreturn isrunning;} public void setrunning (boolean  isrunning) {this.isrunning = isrunning;} public void run () {System.out.println ("Enter Run" ); while (isrunning = = true     
void Main (string[] args) {    trynew MyThread28 (); Mt.start (); Thread.Sleep (+); Mt.setrunning (false); SYSTEM.OUT.PRINTLN ("Assigned to false"catch (Interruptedexception e) {e.printstacktrace ();}}    

Look at the results of the operation:

Entered run, assigned to False

Perhaps the result is a bit strange, obviously isrunning has been set to false, the thread has not stopped it?

This is going to start with the Java memory Model (JMM), where the virtual machine will be described in detail. Depending on the main memory in the Jmm,java, different threads have their own working memory, and the same variable value has one copy in main memory, and if the thread uses this variable, it has an identical copy in its working memory. Each time the thread enters the variable value from main memory, the thread synchronizes the variable from the working memory back into main memory each time it executes.

Printing results occur because of a different step in the main memory and in the working memory. Because the run () method is executed with a copy of the main memory isrunning, and the setup isrunning is done in the main function, in other words, the isrunning setting is the isrunning in main memory, and the isrunning of the main memory is updated , the isrunning in the thread's working memory is not updated, and of course it has been looped, because for the thread, its isrunning is still true.

Solving this problem is simple, add volatile to the IsRunning keyword. Adding volatile means that each time the value of isrunning is read, the isrunning is synchronized from the main memory to the working memory of the thread, and then the current time is the latest isrunning. Take a look at the run effect of the volatile keyword for isrunning:

Entered run, the assigned value is False, the thread is stopped.

See this thread stopped because the most recent isrunning value was read from main memory, the isrunning in the thread's working memory became false, and the natural while loop ended.

This is the effect of volatile, a variable modified by volatile, to ensure that each read is the most recent value. Thread safety revolves around the Two characteristics of visibility and atomicity , andvolatile solves the visibility of variables across multiple threads, but does not guarantee atomicity .

Synchronized, in addition to the protection of atomicity, in fact, but also to ensure the visibility of. Because synchronized either synchronous or synchronized blocks of code, the primary memory data is copied into the working memory, the synchronization block ends, and the data in the working memory is updated to main memory so that the data in the main memory must be up-to-date.

There is no guarantee of thread safety for atomic classes

Atomic operations indicate that an operation is indivisible, and no other thread can break or check for variables that are in an atomic operation. An atomic class is a class that can be used by an atomic operation, which guarantees thread safety without a lock.

But this thread safety is not absolute, and in the case of logic the output is also random, such as

 public class threaddomain29{public static atomicinteger airef = Span style= "color: #0000ff;" >new Atomicinteger (); public void Addnum () { System.out.println (Thread.CurrentThread (). GetName () + "added 100 Result:" + Airef.addandget (100         
Extends thread{    privatepublicthis.td =void run () {td.addnum ();}}    
PublicStaticvoidMain (string[] args) {try {ThreadDomain29 TD = new ThreadDomain29 (); mythread29[] Mt = new mythread29[5for (int i = 0; i < mt.length; I++) {Mt[i] = new MyThread29 (TD);} for (int i = 0; i < mt.length; I++) {Mt[i].start ();} Thread.Sleep (1000catch (Interruptedexception e) {e.printstacktrace ();}}  

Here's an integer atomic class Atomicinteger to see the results:

Thread-1 added 100 After the result:Thread-4 added 100 after the result:Thread-3 added 100 after the result: theThread-2 added 100 after the result:  Thread-0 added 100 results: 100505

Obviously, the result is correct, but not what we want, because we definitely want the output to be added in order, and now it's 200, 500, 400, 300, 100. The cause of this problem is that both airef.addandget (100) and Aairef.addandget (1) are divisible.

The solution is to add synchronized to the Addnum method.

Synchronized lock class method, volatile keyword, and other

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.