Java's synchronized keywords have many usage, such as synchronization methods, synchronization objects, synchronization code blocks, and synchronization classes. It may be a bit messy for beginners, but in the final analysis, it is still the synchronization of objects (or classes, A thread acquires the Lock of an object, not a method lock, or a code block lock.
In this example, object A is like a person holding a key. Many others (threads) want to pass one or several doors, these doors are all locked by this object (synchronized (A). There is only one key, and one key can open all the doors locked by. Anyone who wants to pass one of these doors needs to take the key from the object. after the person has the key, if other people want to pass this door or another door, they all need to wait for the key to be available (BLOCKED). After the previous person returns the key to the object, other people can get the key to pass through the door.
After talking about a bunch of things, I don't know if anyone understands it. Let's use an example to explain it:
1. synchronization object
Public static class testobject {</P> <p> Public synchronized void a () {<br/> log. I ("hxd", "current thread id =" + thread. currentthread (). GETID (); <br/> try {<br/> thread. currentthread (). sleep (2000); <br/>}< br/> catch (exception E) {</P> <p >}< br/>/* <br/> Public void B () {<br/> synchronized (this) {<br/> log. I ("hxd", "current thread id =" + thread. currentthread (). GETID (); <br/> try {<br/> thread. currentthread (). sleep (2000); <br/>}< br/> catch (exception E) {</P> <p >}< br/>}</P> <p> byte [] Lock = new byte [0]; <br/> Public void C () {<br/> synchronized (LOCK) {<br/> log. I ("hxd", "current thread id =" + thread. currentthread (). GETID (); <br/> try {<br/> thread. currentthread (). sleep (2000); <br/>}< br/> catch (exception E) {</P> <p >}< br/> */</P> <p >}< br/> final testobject mtest = new testobject (); <br/> button BTN = (button) findviewbyid (R. id. BTN); <br/> BTN. setonclicklistener (New onclicklistener () {<br/> Public void onclick (view v) {<br/> New thread (New runnable () {<br/> Public void run () {<br/> mtest. A (); <br/> // mtest. B (); <br/> // mtest. C (); <br/>}< br/> }). start (); <br/>}< br/> });
The synchronization effects of functions A, B, and C are the same, and the essence is to obtain the object lock.
In the method A and B, the lock holder (object) is the object that calls the method, and in the method C, the lock holder (object) is the member variable lock.
Running result:
Print the information once every 2 seconds.
2. Synchronization class
Public static class testobject {</P> <p> Public synchronized static void a () {<br/> log. I ("hxd", "current thread id =" + thread. currentthread (). GETID (); <br/> try {<br/> thread. currentthread (). sleep (2000); <br/>}< br/> catch (exception E) {</P> <p >}< br/>/* <br/> Public void B () {<br/> synchronized (testobject. class) {<br/> log. I ("hxd", "current thread id =" + thread. currentthread (). GETID (); <br/> try {<br/> thread. currentthread (). sleep (2000); <br/>}< br/> catch (exception E) {</P> <p >}< br/>}</P> <p> static byte [] Lock = new byte [0]; <br/> Public void C () {<br/> synchronized (LOCK) {<br/> log. I ("hxd", "current thread id =" + thread. currentthread (). GETID (); <br/> try {<br/> thread. currentthread (). sleep (2000); <br/>}< br/> catch (exception E) {</P> <p >}< br/> */</P> <p >}< br/> final testobject mtest = new testobject (); <br/> button BTN = (button) findviewbyid (R. id. BTN); <br/> BTN. setonclicklistener (New onclicklistener () {<br/> Public void onclick (view v) {<br/> New thread (New runnable () {<br/> Public void run () {<br/> mtest. A (); <br/> // mtest. B (); <br/> // mtest. C (); <br/>}< br/> }). start (); <br/>}< br/> });
The synchronization effects of functions A, B, and C are the same, and the essence is to obtain the class lock.
In the method A and B, the lock holder (class) is testobject. In the method C, the lock holder (object) is the member variable lock.
First, let's look at method A. Because static makes this method belong to the testobject class rather than the object, the lock is held by the class rather than the object. Similarly, in C, the lock is also static. Therefore, the lock is also held by the testobject class rather than the object.
Running result:
Print the information once every 2 seconds.
If it is changed to the following call method, no synchronization is formed.
Final testobject mtest1 = new testobject (); <br/> final testobject mtest2 = new testobject (); <br/> button BTN = (button) findviewbyid (R. id. BTN); <br/> BTN. setonclicklistener (New onclicklistener () {<br/> Public void onclick (view v) {<br/> New thread (New runnable () {<br/> Public void run () {<br/> mtest1.a (); <br/> // mtest1. B (); <br/> // mtest1.c (); <br/>}< br/> }). start (); <br/> New thread (New runnable () {<br/> Public void run () {<br/> mtest2.a (); <br/> // mtest2. B (); <br/> // mtest2.c (); <br/>}< br/> }). start (); <br/>}< br/> });
3. Verify whether different methods of the same object constitute synchronization.
Public static class testobject {</P> <p> Public synchronized void a () {<br/> log. I ("hxd", "a current thread id =" + thread. currentthread (). GETID (); <br/> try {<br/> thread. currentthread (). sleep (2000); <br/>}< br/> catch (exception E) {</P> <p >}< br/>}</P> <p> Public synchronized void B () {<br/> log. I ("hxd", "B Current thread id =" + thread. currentthread (). GETID (); <br/> try {<br/> thread. currentthread (). sleep (2000); <br/>}< br/> catch (exception E) {</P> <p >}< br/> final testobject mtest1 = new testobject (); <br/> button BTN = (button) findviewbyid (R. id. BTN); <br/> BTN. setonclicklistener (New onclicklistener () {<br/> Public void onclick (view v) {<br/> New thread (New runnable () {<br/> Public void run () {<br/> mtest1.a (); <br/>}< br/> }). start (); <br/> New thread (New runnable () {<br/> Public void run () {<br/> mtest1. B (); <br/>}< br/> }). start (); <br/>}< br/> });
Running result:
Print the information once every two seconds. It is verified that only one key can open all the doors locked by the object. That is to say, even different functions in the same object constitute synchronization, because only one key is available.
It can be inferred that the same is true for class locks.
4. verify whether the lock is an object or an object reference.
In Java, objects exist in the heap, and object references exist in the stack. The transfer of objects in functions is only the transfer of references. So, in synchronized () is the object itself or the object reference? Here I use the following methods for verification:
1. Thread a acquires the Lock of object A and sleep () for 10 seconds;
2. during sleep, object A points to another new object;
3. Create thread B and try to obtain the Lock of thread.
Public static class testobject {</P> <p> Public synchronized void a () {<br/> log. I ("hxd", "a current thread id =" + thread. currentthread (). GETID (); <br/> try {<br/> thread. currentthread (). sleep (10000); <br/>}< br/> catch (exception E) {</P> <p >}< br/> button BTN = (button) findviewbyid (R. id. BTN); <br/> BTN. setonclicklistener (New onclicklistener () {<br/> Public void onclick (view v) {<br/> New thread (New runnable () {<br/> Public void run () {<br/> mtest1.a (); <br/>}< br/> }). start (); <br/>}< br/>}); <br/> button btn1 = (button) findviewbyid (R. id. btn1); <br/> btn1.setonclicklistener (New onclicklistener () {<br/> @ override <br/> Public void onclick (view V) {<br/> mtest1 = new testobject (); </P> <p >}</P> <p >}); <br/>
Running result:
When thread B is created and the lock of thread a is obtained, function a is successfully executed.
Analysis:
Thread A obtains the Lock of object A, rather than the reference lock of the object. When the button is clicked, mtest1 (Object Reference) is directed to the new object, the lock obtained by thread B is the lock of the new object. This lock is irrelevant to the lock obtained by thread A. Therefore, function A can be successfully executed.
The writing is a bit messy, please point out something wrong.