Java Synchronized keyword, asynchronous ynchronized

Source: Internet
Author: User

Java Synchronized keyword, asynchronous ynchronized
Content

  • Synchronized keyword
  • Example
  • Synchronized Method
  • Intrinsic Locks and Synchronization
  • References
Download the Demo Synchronized keyword

Java provides two basic synchronization mechanisms:SynchronizedMethod (SynchronizedMethods) andSynchronizedStatement (SynchronizedStatements ).

Example

Let's talk about the Java Synchronized keyword. When it is used to modify a method or a code block, it can ensure that only one thread executes the code segment at the same time.

  • When two threads access the same objectSynchronized (this)When a code block is executed, only one thread can execute the code, and the other thread must wait until the thread has finished executing the Code;
  • However, when a thread accesses an objectSynchronized (this)When synchronizing code blocks, another thread can still access non-Synchronized (this)Code block;
  • In particular, when a thread accesses an objectSynchronized (this)When the code block, other threadsSynchronized (this)The access to the code block will also be blocked;
  • The above rules apply to other Object locks.

The following code is used:

package cn.db.syncdemo;
 
public class NewClass {
    /**
* Synchronization Method
     */
    public void synchronizedMethod() {
        synchronized (this) {
            int i = 5;
            while (i-- > 0) {
                System.out.println(Thread.currentThread().getName() + " : " + i
                        + " synchronized method");
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    System.out.println(e.toString());
                }
            }
        }
    }
 
    /**
* Synchronization method 2
     */
    public void synchronizedMethod2() {
        synchronized (this) {
            int i = 5;
            while (i-- > 0) {
                System.out.println(Thread.currentThread().getName() + " : " + i
                        + " synchronized method 2");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    System.out.println(e.toString());
                }
            }
        }
    }
 
    /**
* Non-synchronous method
     */
    public void nonSynchronizedMethod() {
        int i = 5;
        while (i-- > 0) {
            System.out.println(Thread.currentThread().getName() + " : " + i
                    + " nonSynchronized method");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                System.out.println(e.toString());
            }
        }
    }
 
    public static void main(String[] args) {
        final NewClass mClass = new NewClass();
 
// Both t1 and t2 need to access the same synchronization method synchronizedMethod
        Thread t1 = new Thread(new Runnable() {
            public void run() {
                mClass.synchronizedMethod();
            }
        }, "Thread 1");
        Thread t2 = new Thread(new Runnable() {
            public void run() {
                mClass.synchronizedMethod();
            }
        }, "Thread 2");
// T3 to access another synchronization method synchronizedMethod2
        Thread t3 = new Thread(new Runnable() {
            public void run() {
                mClass.synchronizedMethod2();
            }
        }, "Thread 3");
 
// T4 access non-synchronous method nonSynchronizedMethod
        Thread t4 = new Thread(new Runnable() {
            public void run() {
                mClass.nonSynchronizedMethod();
            }
        }, "Thread 4");
 
        t1.start();
        t2.start();
        t3.start();
        t4.start();
 
    }
}

Running result:

Thread 4 : 4 nonSynchronized method
Thread 1 : 4 synchronized method
Thread 4 : 3 nonSynchronized method
Thread 4 : 2 nonSynchronized method
Thread 1 : 3 synchronized method
Thread 4 : 1 nonSynchronized method
Thread 4 : 0 nonSynchronized method
Thread 1 : 2 synchronized method
Thread 1 : 1 synchronized method
Thread 1 : 0 synchronized method
Thread 3 : 4 synchronized method 2
Thread 3 : 3 synchronized method 2
Thread 3 : 2 synchronized method 2
Thread 3 : 1 synchronized method 2
Thread 3 : 0 synchronized method 2
Thread 2 : 4 synchronized method
Thread 2 : 3 synchronized method
Thread 2 : 2 synchronized method
Thread 2 : 1 synchronized method
Thread 2 : 0 synchronized method

Note:

  • T4 non-synchronous access methodNonSynchronizedMethod2, Can be accessed at any time, so "thread 4 :......" What appears is irregular and staggered;
  • Both t1 and t2 must access the same synchronization method.SynchronizedMethodSo "thread 1 :......" And "thread 2 :......" It will never be staggered. After one thread is accessed, the other thread can access it;
  • For t3, t3 automatically accesses another Synchronization MethodSynchronizedMethod2And no other threads can access this method. When t3 accesses this method, other synchronization methods are also locked :......" Is continuous;
  • If you do not check t4, that is, there is no such thread, the result will be:
Thread 1 : 4 synchronized method
Thread 1 : 3 synchronized method
Thread 1 : 2 synchronized method
Thread 1 : 1 synchronized method
Thread 1 : 0 synchronized method
Thread 3 : 4 synchronized method 2
Thread 3 : 3 synchronized method 2
Thread 3 : 2 synchronized method 2
Thread 3 : 1 synchronized method 2
Thread 3 : 0 synchronized method 2
Thread 2 : 4 synchronized method
Thread 2 : 3 synchronized method
Thread 2 : 2 synchronized method
Thread 2 : 1 synchronized method
Thread 2 : 0 synchronized method

Note: thread 2 will never appear before thread 1, and thread 2 must wait for thread 1 to complete access before it can be accessed. When thread 3 is accessed, neither thread 1 nor thread 2 can be accessed. Although there is no thread to compete with thread 3, all three threads access two Synchronization Methods.

Synchronized Method

To make a method a synchronous method, simply add the Declaration to itsynchronizedKeyword:

package cn.db.syncdemo;
 
public class SynchronizedCounter {
    private int c = 0;
 
    public synchronized void increment() {
        c++;
    }
 
    public synchronized void decrement() {
        c--;
    }
 
    public synchronized int value() {
        return c;
    }
}

IfcountYesSynchronizedCounterAnd convert these methods SynchronizedThe method has two effects:

  • First, on the same object, it is impossible to call the synchronized Method in a staggered manner. When a thread is executing an object'sSynchronizedAll calls to thisSynchronizedOther threads of the method will be suspended until the first thread completes;
  • Second, whenSynchronizedWhen the method exits, it automatically creates a pre-relation (happens-before relationship) for any subsequent calls to the synchronization method of the same object ). This ensures that the object state changes are visible to all threads.

Note: The constructor cannot beSynchronizedThat is to say,synchronizedKeyword modifier constructor is a syntax error.SynchronizedThe constructor is meaningless, because when an object is created, only the thread that creates the object can access it.

Warning:When constructing an object to share data between threads, you must be very careful. The reference of an object cannot be "leaked" too early ". For example, if you want to maintaininstancesList, which contains every instance of the class. You may use the following code in your constructor:

instances.add(this);

However, when the object construction is complete, other threads useinstancesAccess Object.

SynchronizedThe method uses a simple policy to prevent thread interference and memory consistency errors: if an object is visible to multiple threads, all the variables that read or write the object passsynchronizedMethod. (An important exception: final field. An object cannot be modified after it is constructed. It can be safely read using a non-synchronized Method once it is constructed ). Intrinsic Locks and Synchronization

Synchronization is built on an internal entity known as an internal lock (Intrinsic Locks) or locked by the monitor. (API specifications often refer to entities that act as "monitors .) Internal locks play two synchronous roles: Execute the state of the exclusive access object, and establish the necessary visibility of the relationship before occurrence (happens-before relationships.

Each object has an internal lock associated with it. Generally, a thread that requires exclusive and consistent access to the object field must require the internal lock of the object before access, and then release the internal lock after completion. The thread has an internal lock at the time between the requirement and the lock release. As long as a thread has an internal lock, other threads can no longer require this lock. Other threads will be blocked when they try to request a lock.

When a thread releases an internal lock, a previous relationship (happens-before relationship) is established between this action and subsequent actions with the same lock. Synchronized Methods Method

When a thread callsSynchronizedMethod, it automatically obtains the internal lock of the method object, and releases the lock when the method returns. Returns the lock release caused by an uncaptured exception.

You may want to know that a staticSynchronizedWhat happens when a method is called, because a static method is associated with a class instead of an object. In this case, the thread obtains the internal lock of the Class Object related to the Class. Therefore, the static field of the category class is controlled by the lock, which is different from the lock of any class instance. Synchronized statement

CreateSynchronizedAnother way of code isSynchronizedStatement. AndSynchronizedDifferent methods,SynchronizedThe statement must specify the object that provides the internal lock, as shown in the following code:This":

public void addName(String name) {
    synchronized(this) {
        lastName = name;
        nameCount++;
    }
    nameList.add(name);
}

In this example,AddNameMethod needs to be changed synchronouslyLastNameAndNameCountTo avoid synchronous calls to methods of other objects. If noSynchronizedThe statement must have a separate, non-synchronized Method for calling.NameList. add.

Synchronized statements are also useful for fine-grained synchronization to improve concurrency. For exampleMsLunchThere are two instance fields,c1Andc2They will never be used together. Updates to all these fields must be synchronized, but there is no reason to prevent cross-update of c1 and c2 (reduce concurrency by creating an unnecessary code block ). ThereforeSynchronized (this)Instead, they provide separate locks for the two objects. As follows:

public class MsLunch {
    private long c1 = 0;
    private long c2 = 0;
    private Object lock1 = new Object();
    private Object lock2 = new Object();
 
    public void inc1() {
        synchronized(lock1) {
            c1++;
        }
    }
 
    public void inc2() {
        synchronized(lock2) {
            c2++;
        }
    }
}

Be especially careful when using this method. You must make sure that it is truly secure for cross-access affected fields. Reentrant Synchronization

Recall that one thread cannot obtain the lock owned by another thread. But a thread can obtain the locks it already has. If a thread acquires the same lock more than once, it will cause reentrant synchronization ). This describes a situation where Synchronous Code calls a method directly or indirectly. This method also contains the Synchronous Code, and both sets of code use the same lock. If there is no reentrant synchronization, the synchronization code must take many additional preventive actions to avoid the thread blocking itself.

References
  • Https://docs.oracle.com/javase/tutorial/essential/concurrency/syncmeth.html
  • Https://docs.oracle.com/javase/tutorial/essential/concurrency/syncrgb.html

 

Download Demo

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.