When multiple threads call the synchronized synchronous method or synchronized (this) of a different name in the same object, the effect of the call is executed sequentially, which is synchronous, blocking.
This indicates that the synchronized synchronous method or the synchronized (this) synchronous code block has two functions respectively
(1) Synchronized synchronization method
1) block call to other synchronized synchronous method or synchronized (this) synchronous code block
2) Only one thread can execute the code in the synchronized synchronization method at the same time
(2) synchronized (this) synchronous code block
1) block call to other synchronized synchronous method or synchronized (this) synchronous code block
2) Only one thread at a time can execute code in the synchronized (this) synchronous code block
Java also supports the ability to synchronize "any object" as an "object Monitor". This "arbitrary object" is mostly a parameter of instance variables and methods, using synchronized (not this object)
The synchronized (non-this object) format only works in 1: synchronized (not this object x) synchronous code block
1) When multiple threads hold the object monitor as the same object, only one thread can execute the code in the synchronized (not this object x) synchronization code block at the same time
2) When holding "Object Monitor" as the same object, only one thread can execute the code in the synchronized (not this object x) synchronization code block at the same time.
Packagesynblockstring;/*** Created by Administrator on 2017/1/19 0019.*/ Public classService {PrivateString Usernameparam; PrivateString Passwordparam; Private string anystring = new string (); Public voidSetusernamepassword (String username,string password) {Try{ synchronized(anystring) {System.out.println ("Thread Name:" +thread.currentthread (). GetName () + "in" +system.currenttimemillis () + "Go to sync"); Usernameparam=username; Thread.Sleep (2000); Passwordparam=password; System.out.println ("Thread name is:" +thread.currentthread (). GetName () + "in" +system.currenttimemillis () + "Leave Sync"); } }Catch(interruptedexception e) {e.printstacktrace (); } }}
Packagesynblockstring;/*** Created by Administrator on 2017/1/19 0019.*/ Public classThreadaextendsThread {PrivateService service; PublicThreada (Service service) {Super(); This. Service =Service; } Public voidrun () {Service.setusernamepassword ("A", "AA"); }}
Packagesynblockstring;/*** Created by Administrator on 2017/1/19 0019.*/ Public classThreadbextendsThread {PrivateService service; Publicthreadb (Service service) {Super(); This. Service =Service; } Public voidrun () {Service.setusernamepassword ("B", "BB"); }}
Packagesynblockstring;/*** Created by Administrator on 2017/1/19 0019.*/ Public classRun { Public Static voidmain (String [] args) {Service service=NewService (); Threada Threada=NewThreada (service); Threada.setname (A); Threada.start (); THREADB threadb=Newthreadb (service); Threadb.setname (B); Threadb.start (); Threadb.start (); }}
The thread name is: A in 1484823811547 to enter the sync thread name: A in 1484823813559 to leave the sync thread name: B in 1484823813559 to enter the synchronization thread name: B in 1484823815573 to leave the synchronization
If you modify Service.java to
Packagesynblockstring;/*** Created by Administrator on 2017/1/19 0019.*/ Public classService {PrivateString Usernameparam; PrivateString Passwordparam; Public voidSetusernamepassword (String username,string password) {Try{ String anystring = new String (); synchronized(anystring) {System.out.println ("Thread Name:" +thread.currentthread (). GetName () + "in" +system.currenttimemillis () + "Go to sync"); Usernameparam=username; Thread.Sleep (2000); Passwordparam=password; System.out.println ("Thread name is:" +thread.currentthread (). GetName () + "in" +system.currenttimemillis () + "Leave Sync"); } }Catch(interruptedexception e) {e.printstacktrace (); } }}
The thread name is: A in 1484823870625 to enter the synchronization thread name: B in 1484823870625 to enter the synchronization thread name is: B in 1484823872638 leave the sync thread name: A in 1484823872638 leave synchronization
Therefore, when synchronizing using the synchronized (non-this object) synchronous block format, the object monitor must be the same object, and if it is not the same object monitor, the result of the run is the asynchronous invocation, which will cross-run.
Look again at the next example:
PackagesynBlockString2;/*** Created by Administrator on 2017/1/19 0019.*/ Public classService {PrivateString anything =NewString (); Public voidA () {Try { synchronized(anything) {System.out.println ("A Begin"); Thread.Sleep (2000); System.out.println ("A End"); } } Catch(interruptedexception e) {e.printstacktrace (); } } synchronized Public voidB () {System.out.println ("B Begin"); System.out.println ("B End"); }}
PackagesynBlockString2;/*** Created by Administrator on 2017/1/19 0019.*/ Public classThreadaextendsThread {PrivateService service; PublicThreada (Service service) {Super(); This. Service =Service; } Public voidrun () {service.a (); }}
PackagesynBlockString2;/*** Created by Administrator on 2017/1/19 0019.*/ Public classThreadbextendsThread {PrivateService service; Publicthreadb (Service service) {Super(); This. Service =Service; } Public voidrun () {service.b (); }}
PackagesynBlockString2;/*** Created by Administrator on 2017/1/19 0019.*/ Public classRun { Public Static voidmain (String [] args) {Service service=NewService (); Threada Threada=NewThreada (service); Threada.setname (A); Threada.start (); THREADB threadb=Newthreadb (service); Threadb.setname (B); Threadb.start (); }}
Run Result: A BEGIN B begin B Enda end
Because the object monitor is different, the result of the operation is asynchronous
Synchronous code blocks are declared in a non-synchronous synchronized method, and there is no guarantee that the thread that invokes the method performs synchronization/ordering, that is, the order in which the threads invoke the method is unordered, although the order in which they are executed in the synchronization block is synchronous, which makes the problem of dirty reads prone.
Synchronized an arbitrary object as an object monitor