We know that there are two types of synchronized: The synchronization method (synchronized) and the synchronous statement block (synchronized block). So what are the differences and the pros and cons of these two?
Synchronizedmethod:
Advantages: Simple and clear code, easy maintenance
Disadvantage: The synchronization of particles through the large, not conducive to concurrency, not flexible, default with this object or the class lock synchronization
Synchronizedblock:
Advantages: Flexible, can use arbitrary object lock; Synchronization granularity is small, concurrency is higher
Cons: Code is more complex and not easy to maintain
Contrast:
Synchronized Method:
The default lock is this (decorated non-static method) or. Class (decorated static method). Once the entire object is locked, other synchronization methods in the object will not be accessible, which may result in a decrease in the concurrency of the methods that would otherwise be irrelevant. Especially when the synchronization method is very large, but only a small piece of code to access the shared data, this time with the synchronization block more appropriate.
synchronized void foo () { ...} void foo () { synchronized (this) { ... }}
public class MyClass { //Locks Myclass.class public static synchronized void foo () {//do something } // Similar public static void Foo () { synchronized (myclass.class) {//do something } }}
Synchronized BLOCK:
You can use the lock of any object to lock the synchronization block, which is very flexible. Adjust the granularity of the synchronization itself.
Using specific Locksobject Inputlock = new Object (), Object outputlock = new Object ();p rivate void Someinputrelatedwork ( { Synchronize (inputlock) { ... }} private void Someoutputrelatedwork () { Synchronize (outputlock) { ... }}
Two methods can be executed at the same time, as long as two threads to obtain a lock (a live output lock, a gain input lock), if changed to synchronous method, there is no way to execute at the same time. And you can decide to use different locks to lock different blocks of code to achieve synchronization according to your own needs.
For example, the following program: Modifying a list's thread does not block the thread that modifies the map
Private list<foo> myList = new arraylist<foo> ();p rivate map<string,bar) MyMap = new Hashmap<string,bar > ();p ublic Void put (String s, Bar b) { synchronized (myMap) { mymap.put (s,b); Then some thing, a while, like a database access or RPC or notifying listeners }}public void Haskey (St Ring S,) { synchronized (myMap) { Mymap.haskey (s); }} public void Add (Foo f) { synchronized (myList) { mylist.add (f);//Then some thing A database access or RPC or notifying listeners }}public Thing Getmedianfoo () { Foo med = null; Synchronized (myList) { collections.sort (myList); Med = Mylist.get (Mylist.size ()/2); } return med;}
Describes the concurrency of the two methods:
JVM support for Synchronized method and Synchronizedblock on the instruction set;
Opcode |
Operand (s) |
Description |
Monitorenter |
None |
Pop ObjectRef, acquire the lock associated with ObjectRef |
Monitorexit |
None |
Pop ObjectRef, release the lock associated with ObjectRef |
Synchronized Block
Class Kitchensync { private int[] Intarray = new INT[10]; void Reverseorder () { synchronized (this) { int halfway = INTARRAY.LENGTH/2; for (int i = 0; i < halfway; ++i) { int upperindex = intarray.length-1-i; int save = Intarray[upperindex]; Intarray[upperindex] = Intarray[i]; Intarray[i] = Save;}} } // ...}
Compiled byte code:
First place the reference to the object to lock into local//variable 1. This local variable is used by both the//Monitorenter and monitorexit instructions. 0 aload_0//Push local var 0 (the This reference) 1 Astore_1//Store to local Var 1//now acquire the LOC K on the referenced object//Push local var 1 (the This reference; the 2 aload_1//object to lock )//POP reference, acquire the lock 3 monitorenter//on referenced object//the code of the Synchroniz Ed Block begins here. A thread would not//execute the next instruction, ALOAD_0, until a lock have been//successfully acquired on the This refer ence above. 4 aload_0//Push the object ref at LOC var 0 (the This ref)//Pop object ref, push ref to Instanc e variable//intarray 5 GetField #4 8 arraylength//POP array ref, push int array length 9 iconst_2 PUSH constant int idiv//Pop-ints, divide, push int result//Pop int to local var 3:11 istore_3//int halfway = intarray.length/2;//this Is the start of the code for the for LOOP12 iconst_0//Push constant int 013 Istore 4//pops into local var 2: int i = 0;15 goto//Jump-to-loop condition check//This is the start of the body of the A for LOOP18 aload_0 Push the object ref at LOC var 0 (the This ref)//Pop object ref, push ref to instance variable IntArray19 GetField #4 arraylength//POP array ref, push int array length23 iconst_1/push Constant int 124 Isub//Pop II INTs, subtract, push int result25 iload 4//push int at local var 4 (i) 27 Isub//Pop ints, subtract, push int result//pop int into local var 5:28 istore 5// int upperindex = intarray.length-1-i;30 aload_0//Push the object ref at LOC var 0 (the This ref) Pop Object ref, PUSH ref to instance variable//intArray31 GetField #4 iload 5//Push int at local var 5 (Upperin DEX) Iaload//Pop index, ARRAYREF, push int at Arrayref[index]//pop into local var 6:37 istore 6//int save = intarray[upperindex];39 Aload_0//Push the object ref at LOC var 0 (the This ref) Pop object ref, push ref to instance variable//intArray40 GetField #4 iload 5//Push I NT at local var 5 (Upperindex) ALOAD_0//Push the object ref at LOC var 0 (the This ref)//Pop O Bject ref, push ref to instance variable//intArray46 GetField #4 iload 4//push int at local V AR 4 (i) Iaload//Pop index, ARRAYREF, push int at Arrayref[index]//Set Arrayref[index] = Valu e:52 Iastore//Intarray[upperindex] = intarray[i];53 aload_0//Push the object ref at LOC var 0 (The This RE f)//PoP object ref, push ref to instance variable//intArray54 GetField #4 iload 4//push int at Loca L var 4 (i) Iload 6//Push int at local var 6 (Save)//Set Arrayref[index] = value:61 Iastore Intarray[i] = save;//The body of the For loop are now done, this instruction does//the incrementing of the loop VA Riable i62 iinc 4 1//Increment by 1 int @ local var 4: ++i;//This is the FOR loop condition check:65 iload 4 push int at local var 4 (i) iload_3//Push int at local var 3 (halfway)//POP II INTs, com Pare, jump if less than to68 IF_ICMPLT +//top of For loop body:for (; i < halfway;)//The Code of the synchronized Block ends here//The next instructions unlock the object, making it available//for other threads. The reference to the locked object is stored//in local variable 1 above.71 aload_1//Push local var 1 (The T His reference) Monitorexit//PoP ref, unlock object73 return//return normally from method//-a catch clause for any exception thrown (and not caught//from within the synchronized block. If An exception are thrown,//the locked object is unlocked, making it available for other//threads.74 aload_1 Push Local var 1 (the This reference) Monitorexit//Pop ref, Unlock object76 athrow//rethrow th E same exception//The exception table shows the "Catch all" clause covers the//entire synchronized block, from just Afte R The lock is acquired//-just before the lock is released. Exception table:from to target type 4
Synchronized method
Class HeatSync { private int[] Intarray = new INT[10]; synchronized void Reverseorder () { int halfway = INTARRAY.LENGTH/2; for (int i = 0; i < halfway; ++i) { int upperindex = intarray.length-1-i; int save = Intarray[upperindex]; Intarray[upperindex] = Intarray[i]; Intarray[i] = save; } } // ...}
Compiled byte code:
0 aload_0//Push the object ref at LOC var 0 (the This ref)//Pop object ref, push ref to instance Variable//intarray 1 GetField #4 4 arraylength//POP array ref, push int array length 5 iconst_2 PUSH constant int 2 6 idiv//Pop-ints, divide, push int result//pop int into local V AR 1:7 istore_1//int halfway = intarray.length/2;//This was the start of the code for the For loop 8 iconst_0 Push INT constant 0 9 istore_2//Pop into local var 2:int i = 0;10 goto si//jump to For loop condition check//This was the start of the body of the for LOOP13 aload_0//Push the object ref at LOC var 0 (the This ref) Pop object ref, push ref to instance variable//intArray14 GetField #4 arraylength Pop array ref, push int array length18 iconst_1/push constant INT 119 isub//Pop, ints, subtract, Push int result20 iload_2//push int at local var 2 (i) Isub//Pop II ints, subtract, push int result//pop int into local var 3:22 istore_3//int upperindex = intarray.length-1-i;23 aload_0//Push the object ref At loc var 0 ("This ref")//Pop object ref, push ref to instance variable//intArray24 GetField #4 iload_3//Push int at local var 3 (upperindex) Iaload//POPs index, ARRAYREF, Push int at Arrayref[index]//Pop into local var 4:29 istore 4//int save = intarray[upperindex];31 Aload_0 Push the object ref at LOC var 0 (the This ref)//Pop object ref, push ref to instance variable IntArray32 GetField #4 iload_3//push int at local var 3 (upperindex) aload_0//Push th E object ref at loc var 0 (the This ref)//Pop object ref, push ref to instance variable intArray37 GetField #4 iload_2//push int at local var 2 (i) Iaload//POPs index, ARRAYREF, Push int at Arrayref[index] Pop value, index, and arrayref,//Set Arrayref[index] = value:42 iastore//Intarray [Upperindex] = intarray[i];43 aload_0//Push the object ref at LOC var 0 (the This ref)//Pop Obje CT ref, push ref to instance variable//intArray44 GetField #4 iload_2//push int at local VAR 2 (i) Iload 4//Push int at local var 4 (Save)//Pop value, index, and Arrayref, Set Arrayref[index] = value:50 iastore//intarray[i] = save;//The body of the For loop are now do, this InStr Uction does//The incrementing of the loop variable i51 iinc 2 1//Increment by 1 int at local var 2: ++i;// The For loop condition check:54 iload_2//push int @ local var 2 (i) iload_1//push int at local var 1 ( Halfway) Pop II INTs, compare, jump if less than to56 if_icmplt//Top of For loop body:for (; i < halfway;) return return (void) from method
Comparing the bytecode above will reveal that the byte code of the synchronization method is more efficient than the byte code of the synchronization block, with fewer instructions; Synchronized method does not have code to enter and leave the monitor, and the compiler does not create an exception table for the HeatSync method.
Therefore, Synchronized method and Synchronized block are not absolute who better than who, concrete case specific analysis. The last thing to say is, don't use it for synchronized, only when you think about designing thread-safe classes. Because the locking unlock all need the overhead, can not use.
Java Synchronized Keyword implementation Synchronization (ii)