Java multi-thread (2) Synchronization

Source: Internet
Author: User

Java multi-thread (2) Synchronization

If your java infrastructure is weak or you are not familiar with java multithreading, read this article java multithreading (1) thread definition, status, and attributes.

Synchronization has always been a difficult issue in java multithreading and is rarely used in android development. However, this is not the reason why we are not familiar with synchronization. I hope this article will allow more people to understand and apply java synchronization.
In multi-threaded applications, two or more threads need to share access to the same data. If two threads access the same object and each thread calls a method to modify the object, this situation is usually a competitive condition.
The most understandable example of the competition condition is: for example, train tickets are certain for train tickets, but the window for selling train tickets is everywhere, and each window is equivalent to a thread, so many threads share all the train ticket resources. And it cannot guarantee its atomicity. If two threads use this resource at the same time, the train tickets they retrieve are the same (with the same seat number ), this will cause trouble to passengers. The solution is that when a thread wants to use the train ticket resource, we will give it a lock and wait for it to lock the resource to another thread. In this way, the above situation will not occur.

1. Lock Object
The synchronized keyword automatically provides locks and related conditions. It is very convenient to use synchronized when explicit locks are required, but when we understand the ReentrantLock class and condition object, we can better understand the synchronized keyword. ReentrantLock is introduced in java se 5.0. The structure of the block protected by ReentrantLock is as follows:

mLock.lock();try{...}finally{mLock.unlock();}

This structure ensures that only one thread enters the critical section at any time. Once a thread blocks the lock object, no other thread can use the lock statement. When other threads call lock, they are blocked until the first thread releases the lock Object. It is necessary to put the unlocked operation in finally. If an exception occurs in the critical section, the lock must be released. Otherwise, other threads will be blocked forever.

2. Condition object
When entering the critical section, it is found that a condition can be executed only after it is met. A condition object is used to manage threads that have obtained a lock but cannot do useful work. A condition object is also called a condition variable.
Let's take a look at the following example to see why conditional objects are needed.

Assume that we need to use bank transfers in a scenario. We first write the class of the Bank, and its constructor needs to input the account quantity and account amount.

public class Bank {private double[] accounts;    private Lock bankLock;    public Bank(int n,double initialBalance){        accounts=new double[n];        bankLock=new ReentrantLock();        for (int i=0;i

Next, we need to make a withdrawal and write a method for the withdrawal. from is the transferor, to is the receiver, and amount is the transfer amount. As a result, we find that the balance of the transferor is insufficient, if another thread saves enough money to the transferer, the transfer can be successful, but the thread has obtained the lock, and it is exclusive, other threads cannot obtain the lock for deposit operations, which is why we need to introduce the condition object.

   public void transfer(int from,int to,int amount){        bankLock.lock();        try{            while (accounts[from]

A lock object has multiple related condition objects. You can use the newCondition method to obtain a condition object. After obtaining the condition object, we call the await method. The current thread is blocked and the lock is abandoned.

Public class Bank {private double [] accounts; private Lock bankLock; private Condition condition; public Bank (int n, double initialBalance) {accounts = new double [n]; bankLock = new ReentrantLock (); // obtain the condition object condition = bankLock. newCondition (); for (int I = 0; I

The waiting thread is essentially different from the thread that calls the await method. Once a thread calls the await method, it enters the waiting set of the condition. When the lock is available, the thread cannot be unlocked immediately. On the contrary, the thread is blocked until another thread calls the signalAll method on the same condition. When another thread is about to transfer money to our previous transferer, it only needs to call condition. signalAll (); this call will reactivate all threads waiting for this condition.
When a thread calls the await method, it cannot reactivate itself and expects other threads to call the signalAll method to activate itself. If there are no other threads to activate the waiting thread, A deadlock occurs. If all other threads are blocked and await is called by the last active thread before the other threads are blocked, no thread can remove the blocking of other threads, and the program will be suspended.
When Will signalAll be called? Normally, it is helpful to call signalAll when the thread direction changes. In this example, when an account balance changes, the waiting thread should have the opportunity to check the balance.

 public void transfer(int from,int to,int amount) throws InterruptedException {        bankLock.lock();        try{            while (accounts[from]

When the signalAll method is called, instead of activating a waiting thread immediately, it only removes the blocking of waiting threads so that these threads can exit the synchronous method of the current thread, access to objects through competition. Another method is signal, which is to randomly remove the blocking of a thread. If the thread still cannot run, it will be blocked again. If no other thread calls signal again, then the system will be deadlocked.

3. Synchronized keyword
The Lock and Condition interfaces provide high Lock Control for program designers. However, in most cases, such control is not required and a mechanism can be used to embed data into the java language. Since Java, every object in Java has an internal lock. If a method is declared with the synchronized keyword, the object lock will protect the entire method. That is to say, to call this method, the thread must obtain the internal object lock.
In other words,

public synchronized void method(){}

Equivalent

public void method(){this.lock.lock();try{}finally{this.lock.unlock();}

In the Bank example above, we can declare the transfer method of the Bank class as synchronized instead of using a display lock.
There is only one condition for the internal object lock. wait is added to a thread to wait for the set. The yyall or y method removes the blocking status of the waiting thread. That is to say, wait is equivalent to calling condition. await (). policyall is equivalent to condition. signalAll ();

In the preceding example, the transfer method can also be written as follows:

    public synchronized void transfer(int from,int to,int amount)throws InterruptedException{        while (accounts[from]

It can be seen that it is much simpler to write code using the synchronized keyword. To understand this code, you must understand that each object has an internal lock and the lock has an internal condition. The lock is used to manage the threads that attempt to enter the synchronized method, and the condition is used to manage the threads that call wait.

4. Synchronization Blocking
As we have said above, every Java object has a lock, the thread can call the synchronous method to obtain the lock, and another mechanism can obtain the lock by entering a synchronous blocking, when the thread is blocked in the following form:

synchronized(obj){}

So he obtained the obj lock. Let's take a look at the Bank class.

public class Bank {private double[] accounts;private Object lock=new Object(); public Bank(int n,double initialBalance){ accounts=new double[n]; for (int i=0;i

Here, the lock object is created only to use the lock held by each Java object. Sometimes developers use an object lock to perform extra atomic operations, which is called client lock. For example, the method of the Vector class is synchronous. Now let's assume that the bank balance is stored in the Vector.

 public void transfer(Vector  accounts,int from,int to,int amount){ accounts.set(from,accounts.get(from)-amount); accounts.set(to,accounts.get(to)+amount;} 

The get and set methods of the Vecror class are synchronized, but this does not help us. After the first call to get is complete, a thread may be deprived of running permission in the transfer method. Therefore, another thread may store different values in the same storage location. However, we can intercept this lock.

 public void transfer(Vector  accounts,int from,int to,int amount){ synchronized(accounts){ accounts.set(from,accounts.get(from)-amount); accounts.set(to,accounts.get(to)+amount; }} 

Client locking (Synchronous Code block) is very fragile and is generally not recommended. Generally, it is best to use classes provided under java. util. concurrent, such as blocking queues. If the synchronization method is suitable for your program, try to use the synchronization method as much as possible, which can reduce the number of code writing and reduce the chance of errors, lock/Condition is used only when the Lock/Condition structure is used to provide unique features.

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.