Roles of synchronized and synchronized

Source: Internet
Author: User

Roles of synchronized and synchronized

I. Synchronization Method

public synchronized void methodAAA(){    //….}

The lock is the object that calls this synchronization method.

Test:
A. if you do not use this keyword to modify the method, the two threads call the method of the same object.
Target class:

Public class TestThread {public void execute () {// synchronized, not modified for (int I = 0; I <100; I ++) {System. out. println (I );}}}

Thread class:

Public class ThreadA implements Runnable {TestThread test = null; public ThreadA (TestThread pTest) {// the object has been introduced externally, so that it is the same object test = pTest ;} public void run () {test.exe cute ();}}

Call:

TestThread test=new TestThread();Runnable runabble=new ThreadA(test);Thread a=new Thread(runabble,"A");                a.start();Thread b=new Thread(runabble,"B");b.start();

Result:
The output numbers are intertwined. This indicates that the two methods are not synchronized. They are called asynchronously in different threads.

B. Modify the target class and add the synchronized modifier.

Public class TestThread {public synchronized void execute () {// synchronized modifier for (int I = 0; I <100; I ++) {System. out. println (I );}}}

Result:
The numbers output are ordered. The numbers A and B are output first, indicating that they are synchronized. Although they are different threads, the two methods are synchronously called.
Note: Although there are two different threads above, they are the same instance object. The following uses different instance objects for testing.

C. Each thread has an independent TestThread object.
Target class:

Public class TestThread {public synchronized void execute () {// synchronized modifier for (int I = 0; I <100; I ++) {System. out. println (I );}}}

Thread class:

public class ThreadA implements Runnable{    public void run() {        TestThread test=new TestThread();        test.execute();    }}

Call:

Runnable runabble=new ThreadA();Thread a=new Thread(runabble,"A");                a.start();Thread b=new Thread(runabble,"B");b.start();

Result:
The output numbers are intertwined. Although the synchronized keyword is added to modify the method, the two methods are still asynchronous when different threads call their own object instances.

Extended:
For such multiple instances, to achieve synchronization, that is, the output number is ordered and output in the thread order, we can add a static variable, lock it (the locked object will be described later ).

Modify target class:

Public class TestThread {private static Object lock = new Object (); // It must be static. Public void execute () {synchronized (lock) {for (int I = 0; I <100; I ++) {System. out. println (I );}}}}

2. synchronous code block

public void method(SomeObject so){    synchronized(so)       //…..    }}

Locking an object actually locks the object reference)
Whoever gets the lock can run the code controlled by it. When there is a clear object as the lock, you can write the program according to the above Code, but when there is no clear object as the lock, just want to synchronize a piece of code, you can create a special instance variable (which must be an object) to act as a lock (the above solution is to add a state lock ).

A. Lock an object. It is not static
Private byte [] lock = new byte [0]; // special instance variable
Target class:

Public class TestThread {private Object lock = new Object (); public void execute () {synchronized (lock) {// adds a lock and locks the Object lock, in the same class instance, it is thread-safe, but different instances are still insecure. Because different instances have different object lock. for (int I = 0; I <100; I ++) {System. out. println (I );}}}}

In fact, locking a method above is equivalent to the following:

Public void execute () {synchronized (this) {// The synchronization object is of course for (int I = 0; I <100; I ++) {System. out. println (I );}}}

B. Lock an object or method. It is static.
In this way, it locks the class to which the object belongs.

Public synchronized static void execute () {//...} is equivalent
Public class TestThread {public static void execute () {synchronized (TestThread. class ){//}}}

Test:

Target class:

Public class TestThread {private static Object lock = new Object (); public synchronized static void execute () {// synchronous static method for (int I = 0; I <100; I ++) {System. out. println (I) ;}} public static void execute1 () {for (int I = 0; I <100; I ++) {System. out. println (I) ;}} public void test () {execute (); // The output is ordered, indicating that it is synchronized // execute1 (); // output is unnecessary, indicating asynchronous} Thread class: Call different methods, so two thread classes are established: public class ThreadA implements Runnable {publi C void run () {TestThread.exe cute (); // call the synchronized static method} public class ThreadB implements Runnable {public void run () {TestThread test = new TestThread (); test. test (); // call non-synchronous non-static method} call: Runnable runabbleA = new ThreadA (); Thread a = new Thread (runabbleA, "A");. start (); Runnable runabbleB = new ThreadB (); Thread B = new Thread (runabbleB, "B"); B. start (); Note: When synchronized is used to lock an object, if the object is modified in the lock code segment, the lock disappears. See the following example: Target class: public class TestThread {private static final class TestThreadHolder {private static TestThread theSingleton = new TestThread (); public static TestThread getSingleton () {return theSingleton ;} private TestThreadHolder () {}} private Vector ve = null; private Object lock = new Object (); private TestThread () {ve = new Vector (); initialize ();} public static TestThread getInstance () {return TestThreadHolder. getSingleton ();} private void initialize () {for (int I = 0; I <100; I ++) {ve. add (String. valueOf (I) ;}} public void reload () {synchronized (lock) {ve = null; ve = new Vector (); // lock = "abc "; for (int I = 0; I <100; I ++) {ve. add (String. valueOf (I);} System. out. println ("reload end");} public boolean checkValid (String str) {synchronized (lock) {System. out. println (ve. size (); return ve. contains (str );}}}

Note: The synchronized keyword is added in the reload and checkValid methods to lock the lock Object. The reload and checkValid methods are called for the same object instance in different threads.
In the reload method, comment lock = "abc"; if the lock object is not modified, and output 100 only after reload end is output on the console. This indicates synchronous call.
If you modify the lock object in the reload method, the comment is removed. The result first outputs a number (the current ve size), and then outputs the reload end. It indicates that it is an asynchronous call.

2. Considerations for multithreading in singleton Mode

 public class TestThread {    private static final class TestThreadHolder {        private static TestThread theSingleton = new TestThread();        public static TestThread getSingleton() {            return theSingleton;        }        private TestThreadHolder() {        }    }    private Vector ve =null;    private Object lock=new Object();    private TestThread(){        ve=new Vector();        initialize();    }    public static TestThread getInstance(){        return TestThreadHolder.getSingleton();    }} 

Note: An internal class is added to declare a static object in the internal class, instantiate the singleton class, and initialize the data in the constructor of the singleton class. This ensures that the initialized data is successfully initialized when multiple instances are simultaneously accessed.

Summary:
A. no matter whether the synchronized keyword is applied to methods or objects, the lock it acquires is an object, rather than using A code or function as A lock. Therefore, you should first know the object to be locked.
B. Each object has only one lock associated with it.
C. Implementing synchronization requires a large amount of system overhead as a cost, and may even cause deadlocks. Avoid unnecessary synchronization control as much as possible.

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.