In Java, there are 2 ways to use the Synchronized keyword:
- As a keyword decoration method
- Retouch a block of code
[TOC]
Thread contention
To explore the specific use of synchronized, you can use a simple procedure to illustrate:
Package fc.learn.java.synchronize;import Java.util.Random; Public classlearningsynchronized { Public enumSynctypetag {obj_method, Class_method, Keyward_method, Normal_method}Static classMyrunnableImplementsrunnable{Private void Counting(){ for(inti =0; i<5; i++) {System. out.println(String. Format("thread[%s] count for [%s]", Thread.CurrentThread().GetName(), i));intSleepseconds =NewRandom ().Nextint(); Sleepseconds = sleepseconds%Ten; Sleepseconds = Sleepseconds * sleepseconds; Sleepseconds = sleepseconds%5; System. out.println(String. Format("thread[%s] sleep for 0.%sseconds ", Thread.CurrentThread().GetName(), sleepseconds));Try{Thread.Sleep(Sleepseconds * -); }Catch(Interruptedexception e) {e.Printstacktrace(); } } }Private void Synchronizeobjectmethod() {synchronized( This){Counting(); } }Private void Synchronizeclasstmethod(){synchronized(myrunnable.class){Counting(); } }Private synchronized void Synchronizedmethod(){Counting(); }Private void Normalmethod(){Counting(); }PrivateSynctypetag Syntype; Public myrunnable(Synctypetag type) { This.Syntype= type; }@Override Public void Run() {if( This.Syntype= = Synctypetag.Obj_method) {Synchronizeobjectmethod(); }Else if( This.Syntype= = Synctypetag.Class_method) {Synchronizeclasstmethod(); }Else if( This.Syntype= = Synctypetag.Keyward_method) {Synchronizedmethod(); }Else if( This.Syntype= = Synctypetag.Normal_method) {Normalmethod(); } } } Public Static void Main(string[] args) {Runnable R1 =New myrunnable(Synctypetag.Normal_method); Runnable r2 =New myrunnable(Synctypetag.Normal_method); Thread T1 =NewThread (R1); Thread t2 =NewThread (R2); T1.Start(); T2.Start(); }}
Run the code and you get the following results:
Thread[Thread-1] count for [0]Thread[Thread-0] count for [0]Thread[Thread-1] sleep for 0.4 secondsThread[Thread-0] sleep for 0.1 secondsThread[Thread-0] count for [1]Thread[Thread-0] sleep for 0.4 secondsThread[Thread-1] count for [1]Thread[Thread-1] sleep for 0.0 secondsThread[Thread-1] count for [2]Thread[Thread-1] sleep for 0.1 secondsThread[Thread-1] count for [3]Thread[Thread-0] count for [2]Thread[Thread-1] sleep for 0.4 secondsThread[Thread-0] sleep for 0.1 secondsThread[Thread-0] count for [3]Thread[Thread-0] sleep for 0.4 secondsThread[Thread-1] count for [4]Thread[Thread-1] sleep for 0.4 secondsThread[Thread-0] count for [4]Thread[Thread-0] sleep for 0.1 seconds
That is, in general, the counting () method is used by thread contention
Class lock synchronized (Class)
So let's lock it up and try it. First try the class locking:
// 之前代码太多不再赘述,此处只展示main方法publicstaticvoidmain(String[] args) { newMyRunnable(SyncTypeTag.CLASS_METHOD); newMyRunnable(SyncTypeTag.CLASS_METHOD); new Thread(r1); new Thread(r2); t1.start(); t2.start();}
The following results can be obtained:
Thread[Thread-0] count for [0]Thread[Thread-0] sleep for 0.1 secondsThread[Thread-0] count for [1]Thread[Thread-0] sleep for 0.0 secondsThread[Thread-0] count for [2]Thread[Thread-0] sleep for 0.1 secondsThread[Thread-0] count for [3]Thread[Thread-0] sleep for 0.1 secondsThread[Thread-0] count for [4]Thread[Thread-0] sleep for 0.4 secondsThread[Thread-1] count for [0]Thread[Thread-1] sleep for 0.0 secondsThread[Thread-1] count for [1]Thread[Thread-1] sleep for 0.0 secondsThread[Thread-1] count for [2]Thread[Thread-1] sleep for 0.1 secondsThread[Thread-1] count for [3]Thread[Thread-1] sleep for 0.1 secondsThread[Thread-1] count for [4]Thread[Thread-1] sleep for 0.1 seconds
At this point, the thread no longer contention, the purpose is achieved.
Object-Lock synchronized (object)
Then try the object lock:
// 仔细观察,这里用的 this 也就是说,每个线程用的不是同一把锁privatevoidsynchronizeObjectMethod() { synchronized (this){ counting(); }}publicstaticvoidmain(String[] args) { newMyRunnable(SyncTypeTag.CLASS_METHOD); newMyRunnable(SyncTypeTag.CLASS_METHOD); new Thread(r1); new Thread(r2); t1.start(); t2.start();}
To run the code:
Thread[Thread-1] count for [0]Thread[Thread-0] count for [0]Thread[Thread-1] sleep for 0.0 secondsThread[Thread-0] sleep for 0.4 secondsThread[Thread-1] count for [1]Thread[Thread-1] sleep for 0.1 secondsThread[Thread-1] count for [2]Thread[Thread-1] sleep for 0.4 secondsThread[Thread-0] count for [1]Thread[Thread-0] sleep for 0.4 secondsThread[Thread-1] count for [3]Thread[Thread-1] sleep for 0.4 secondsThread[Thread-0] count for [2]Thread[Thread-0] sleep for 0.1 secondsThread[Thread-0] count for [3]Thread[Thread-0] sleep for 0.0 secondsThread[Thread-0] count for [4]Thread[Thread-0] sleep for 0.1 secondsThread[Thread-1] count for [4]Thread[Thread-1] sleep for 0.0 seconds
It can be found that the lock does not work. This reason is also easy to understand, because the method is used to synchronizeObjectMethod
synchronized(this)
lock, and we have 2 process objects in the counting()
operation of the method, so there will be contention. If the code changes to this:
//Synchronizedobjectmethod modified to this:Private void Synchronizeobjectmethod(Object GlobalLock) {synchronized(GlobalLock) {Counting(); }}//constructor methods and member variables:PrivateSynctypetag Syntype;PrivateObject GlobalLock; Public myrunnable(Synctypetag type, Object lock) { This.Syntype= type; This.GlobalLock= lock;}@Override Public void Run() {if( This.Syntype= = Synctypetag.Obj_method) {Synchronizeobjectmethod( This.GlobalLock); }Else if( This.Syntype= = Synctypetag.Class_method) {Synchronizeclasstmethod(); }Else if( This.Syntype= = Synctypetag.Keyward_method) {Synchronizedmethod(); }Else if( This.Syntype= = Synctypetag.Normal_method) {Normalmethod(); }}//Main method: Public Static void Main(string[] args) {Object GlobalLock =NewObject (); Runnable R1 =New myrunnable(Synctypetag.Obj_method, GlobalLock); Runnable r2 =New myrunnable(Synctypetag.Obj_method, GlobalLock); Thread T1 =NewThread (R1); Thread t2 =NewThread (R2); T1.Start(); T2.Start();}
To run the code:
Thread[Thread-0] count for [0]Thread[Thread-0] sleep for 0.1 secondsThread[Thread-0] count for [1]Thread[Thread-0] sleep for 0.1 secondsThread[Thread-0] count for [2]Thread[Thread-0] sleep for 0.1 secondsThread[Thread-0] count for [3]Thread[Thread-0] sleep for 0.0 secondsThread[Thread-0] count for [4]Thread[Thread-0] sleep for 0.0 secondsThread[Thread-1] count for [0]Thread[Thread-1] sleep for 0.0 secondsThread[Thread-1] count for [1]Thread[Thread-1] sleep for 0.4 secondsThread[Thread-1] count for [2]Thread[Thread-1] sleep for 0.1 secondsThread[Thread-1] count for [3]Thread[Thread-1] sleep for 0.1 secondsThread[Thread-1] count for [4]Thread[Thread-1] sleep for 0.4 seconds
Contention disappears.
Keyword Synchronized method ()
Next try the Synchronized Keyword Direct modification method:
publicstaticvoidmain(String[] args) { new Object(); newMyRunnable(SyncTypeTag.KEYWARD_METHOD, globalLock); newMyRunnable(SyncTypeTag.KEYWARD_METHOD, globalLock); new Thread(r1); new Thread(r2); t1.start(); t2.start();}
To run the code:
Thread[Thread-0] count for [0]Thread[Thread-1] count for [0]Thread[Thread-0] sleep for 0.0 secondsThread[Thread-1] sleep for 0.1 secondsThread[Thread-0] count for [1]Thread[Thread-0] sleep for 0.1 secondsThread[Thread-1] count for [1]Thread[Thread-0] count for [2]Thread[Thread-1] sleep for 0.1 secondsThread[Thread-0] sleep for 0.1 secondsThread[Thread-0] count for [3]Thread[Thread-0] sleep for 0.1 secondsThread[Thread-1] count for [2]Thread[Thread-1] sleep for 0.4 secondsThread[Thread-0] count for [4]Thread[Thread-0] sleep for 0.4 secondsThread[Thread-1] count for [3]Thread[Thread-1] sleep for 0.4 secondsThread[Thread-1] count for [4]Thread[Thread-1] sleep for 0.1 seconds
Will still be used for contention, indicating synchronized modification method, equals synchronized(this)
.
References:
Http://www.cnblogs.com/GnagWang/archive/2011/02/27/1966606.html
Java Thread Safety Synchronize learning