In the project development, may encounter Java multithreading, in order to ensure the normal business data, must be coupled with the lock mechanism, commonly used to deal with synchronized keyword, the current JDK version of synchronized has done a very good optimization, we do not have to consider its performance , but in the actual use, often due to improper handling, resulting in a serious decline in system performance, then how to use synchronized, it must be used in a comprehensive understanding of its use, in the online search for information, given is four ways to use, in fact, can be summed up to two kinds, one is synchronous code block, a Is the synchronization method body, then how to use, see the following test:
Prepare two methods, add to the same variable, and open 10 threads for each method, respectively:
[Java]
public class Threadunit
{
private int i = 0;
Private Object obj1 = new Object ();
Private Object obj2 = new Object ();
Public synchronized Integer doAdd1 (Long start) throws Exception
{
Thread.Sleep (100);
++i;
Thread.Sleep (100);
return i;
}
Public Integer doAdd2 (Long start) throws Exception
{
Thread.Sleep (100);
++i;
Thread.Sleep (100);
return i;
}
}
Related code:
[Java]
10 threads executing method 2 simultaneously
for (int i = 0; I < 10; i++)
{
New Thread (New Messagethread (1, Threadunit)). Start ();
}
10 threads executing method 2 simultaneously
for (int j = 0; J < 10; J + +)
{
New Thread (New Messagethread (2, Threadunit)). Start ();
}
Thread Handling:
[Java]
public void Run ()
{
Try
{
if (operate = = 2)
{
Long start = System.currenttimemillis ();
int i = THREADUNIT.DOADD2 (start);
Long taketime = System.currenttimemillis ()-Start;
System.out.println ("doAdd2 () = i=" + i + ", spendtime=" + taketime + "MS");
Spendtime + = Taketime;
}
Else
{
Long start = System.currenttimemillis ();
int i = THREADUNIT.DOADD1 (start);
Long taketime = System.currenttimemillis ()-Start;
System.out.println ("doAdd1 () = i=" + i + ", spendtime=" + taketime + "MS");
Spendtime + = Taketime;
}
}
catch (Exception e)
{
E.printstacktrace ();
}
}
Operation Result:
1. Add synchronized to all two method bodies
[Java]
Public synchronized Integer doAdd1 (Long start) throws Exception
[Java]
Public synchronized Integer DOADD2 (Long start) throws Exception
Execution Result:
[HTML]
DOADD1 () = I=1, spendtime=203ms
DOADD2 () = i=2, spendtime=406ms
DOADD2 () = i=3, spendtime=609ms
DOADD2 () = i=4, spendtime=796ms
DOADD2 () = i=5, spendtime=1000ms
DOADD2 () = I=6, spendtime=1203ms
DOADD2 () = i=7, spendtime=1406ms
DOADD2 () = I=8, spendtime=1609ms
DOADD2 () = i=9, spendtime=1812ms
DOADD2 () = i=10, spendtime=2015ms
DOADD2 () = i=11, spendtime=2218ms
DOADD1 () = i=12, spendtime=2406ms
DOADD1 () = i=13, spendtime=2609ms
DOADD1 () = i=14, spendtime=2812ms
DOADD1 () = i=15, spendtime=3015ms
DOADD1 () = i=16, spendtime=3218ms
DOADD1 () = i=17, spendtime=3421ms
DOADD1 () = i=18, spendtime=3625ms
DOADD1 () = i=19, spendtime=3828ms
DOADD1 () = i=20, spendtime=4015ms
Elapsed time: 42226ms
Are executed sequentially, the value of the variable does not produce confusion, but it takes time 42226ms
2. Add synchronized to the DoAdd1 method, doAdd2 not Add.
[Java]
Public synchronized Integer doAdd1 (Long start) throws Exception
Execution Result:
[Java]
DoAdd1 Method plus synchronized:
DOADD1 () = i=9, spendtime=204ms
DOADD2 () = i=9, spendtime=188ms
DOADD2 () = i=9, spendtime=188ms
DOADD2 () = i=9, spendtime=188ms
DOADD2 () = i=9, spendtime=188ms
DOADD2 () = i=9, spendtime=188ms
DOADD2 () = i=9, spendtime=188ms
DOADD2 () = i=9, spendtime=188ms
DOADD2 () = i=9, spendtime=188ms
DOADD2 () = i=9, spendtime=188ms
DOADD2 () = i=9, spendtime=188ms
DOADD1 () = i=10, spendtime=391ms
DOADD1 () = i=11, spendtime=610ms
DOADD1 () = i=12, spendtime=813ms
DOADD1 () = i=13, spendtime=1016ms
DOADD1 () = i=14, spendtime=1219ms
DOADD1 () = i=15, spendtime=1422ms
DOADD1 () = i=16, spendtime=1610ms
DOADD1 () = i=17, spendtime=1813ms
DOADD1 () = i=18, spendtime=2016ms
Elapsed time: 12994ms
The DoAdd2 method executes instantaneously, and then the DoAdd1 method is serially executed sequentially. At this point the DoAdd2 method gets the value of the variable has been garbled, doAdd1 get normal. Elapsed time: 12994ms
3. Two methods are not used before synchronized the situation:
Execution Result:
[Java]
DOADD1 () = i=16, spendtime=203ms
DOADD1 () = i=16, spendtime=203ms
DOADD1 () = i=16, spendtime=203ms
DOADD1 () = i=16, spendtime=203ms
DOADD1 () = i=16, spendtime=203ms
DOADD1 () = i=16, spendtime=203ms
DOADD1 () = i=16, spendtime=203ms
DOADD1 () = i=16, spendtime=203ms
DOADD1 () = i=16, spendtime=203ms
DOADD2 () = i=16, spendtime=203ms
DOADD2 () = i=16, spendtime=203ms
DOADD2 () = i=16, spendtime=203ms
DOADD1 () = i=16, spendtime=203ms
DOADD2 () = i=16, spendtime=203ms
DOADD2 () = i=16, spendtime=203ms
DOADD2 () = i=16, spendtime=203ms
DOADD2 () = i=16, spendtime=203ms
DOADD2 () = i=16, spendtime=203ms
DOADD2 () = i=16, spendtime=203ms
DOADD2 () = i=16, spendtime=203ms
Elapsed time: 4060ms
As you can see, the variable value of the two methods gets messed up, but takes a minimum of 4060ms
4. Using a sync block, use different object locks within two methods:
DOADD1:
[Java]
Synchronized (OBJ1)
{
Thread.Sleep (100);
++i;
Thread.Sleep (100);
return i;
}
DOADD2:
[Java]
Synchronized (OBJ2)
{
Thread.Sleep (100);
++i;
Thread.Sleep (100);
return i;
}
Execution Result:
[HTML]
DOADD1 () = i=2, spendtime=203ms
DOADD2 () = i=2, spendtime=203ms
DOADD1 () = i=4, spendtime=406ms
DOADD2 () = i=4, spendtime=406ms
DOADD1 () = I=6, spendtime=609ms
DOADD2 () = I=6, spendtime=609ms
DOADD1 () = I=8, spendtime=812ms
DOADD2 () = I=8, spendtime=812ms
DOADD1 () = i=10, spendtime=1000ms
DOADD2 () = i=10, spendtime=1015ms
DOADD1 () = i=12, spendtime=1203ms
DOADD2 () = i=12, spendtime=1203ms
DOADD1 () = i=14, spendtime=1406ms
DOADD2 () = i=14, spendtime=1406ms
DOADD1 () = i=16, spendtime=1609ms
DOADD2 () = i=16, spendtime=1609ms
DOADD1 () = i=18, spendtime=1812ms
DOADD2 () = i=18, spendtime=1812ms
DOADD1 () = i=20, spendtime=2015ms
DOADD2 () = i=20, spendtime=2015ms
Elapsed time: 22165ms
Two methods orderly alternating execution, non-impact, spend time: 22165ms, relative lock the same object execution time is shortened.
5. Using the synchronization block, use the method parameter as the object lock:
[Java]
Public Integer doAdd1 (Long start) throws Exception
{
Synchronized (start)
{
Thread.Sleep (100);
++i;
Thread.Sleep (100);
return i;
}
}
Execution Result:
[Java]
DOADD1 () = i=15, spendtime=203ms
DOADD1 () = i=15, spendtime=203ms
DOADD1 () = i=15, spendtime=203ms
DOADD1 () = i=15, spendtime=203ms
DOADD1 () = i=15, spendtime=203ms
DOADD1 () = i=15, spendtime=203ms
DOADD1 () = i=15, spendtime=203ms
DOADD2 () = i=15, spendtime=203ms
DOADD2 () = i=15, spendtime=203ms
DOADD1 () = i=15, spendtime=203ms
DOADD1 () = i=15, spendtime=203ms
DOADD2 () = i=15, spendtime=203ms
DOADD2 () = i=15, spendtime=203ms
DOADD2 () = i=15, spendtime=203ms
DOADD2 () = i=15, spendtime=203ms
DOADD2 () = i=15, spendtime=203ms
DOADD2 () = i=15, spendtime=203ms
DOADD2 () = i=15, spendtime=203ms
DOADD1 () = i=15, spendtime=203ms
DOADD2 () = i=15, spendtime=203ms
Elapsed time: 4060ms
The execution effect is the same as the third case, with each parameter as a different object, even with synchronized, which does not have the effect of locking.
6. Change the calling class to a static class, and lock only on one method:
Locking DoAdd1 Method:
[Java]
public static synchronized Integer doAdd1 (Long start) throws Exception
Execution Result:
[HTML]
DOADD1 () = i=9, spendtime=203ms
DOADD2 () = i=9, spendtime=203ms
DOADD2 () = i=9, spendtime=203ms
DOADD2 () = i=9, spendtime=203ms
DOADD2 () = i=9, spendtime=203ms
DOADD2 () = i=9, spendtime=203ms
DOADD2 () = i=9, spendtime=203ms
DOADD2 () = i=9, spendtime=203ms
DOADD2 () = i=9, spendtime=203ms
DOADD2 () = i=9, spendtime=203ms
DOADD2 () = i=9, spendtime=203ms
DOADD1 () = i=10, spendtime=406ms
DOADD1 () = i=11, spendtime=609ms
DOADD1 () = i=12, spendtime=812ms
DOADD1 () = i=13, spendtime=1015ms
DOADD1 () = i=14, spendtime=1218ms
DOADD1 () = i=15, spendtime=1406ms
DOADD1 () = i=16, spendtime=1609ms
DOADD1 () = i=17, spendtime=1812ms
DOADD1 () = i=18, spendtime=2015ms
Elapsed time: 13135ms
Similar to the second case, the DoAdd2 method without locking is executed instantaneously, and the DoAdd1 method is serially executed sequentially.
Summarize:
1. Synchronized the key is to lock the object, if it is the same object, then all the execution threads, must wait for the object lock to be released before execution, if it is a different object, then only the threads associated with each object take effect.
2. Synchronized flocculent on the method body, the object itself is locked by default. For all methods of locking, all are executed sequentially according to the serial rules, and for the method without locking, it is not affected by static class.
3. Reasonable use of synchronized, not only to ensure stability, but also to ensure performance, need to make a trade-off between the two, as far as possible to synchronized the scope of fineness, reasonable control of the business process; object Operation atomization, reduce the use of locks;
Do not blindly add synchronized keywords to the method body, if each method is responsible for dealing with a different business, then try to use the fourth case, using different object lock processing, instead of locking the entire object.
On the test and reasonable use of Java multithreading concurrency synchronized