On the test and reasonable use of Java multithreading concurrency synchronized

Source: Internet
Author: User

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

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.