Java multi-threading, concurrency Series (synchronized) synchronization and locking mechanism

Source: Internet
Author: User
Tags instance method

Each object in Java has a built-in lock that automatically obtains the lock associated with the current instance (this instance) of the executing code class when the program runs to a non-static synchronized synchronization method. Acquiring a lock on an object is also known as acquiring a lock, locking an object, locking on an object, or synchronizing on an object.

当程序运行到synchronized同步方法或代码块时才该对象锁才起作用。

An object has only one lock. Therefore, if a thread obtains the lock, no other thread can get the lock until the first thread releases (or returns) the lock. This also means that no other thread can enter the synchronized method or block of code on the object until the lock is freed.

释放锁是指持锁线程退出了synchronized同步方法或代码块。

Synchronization blocks in Java are marked with synchronized. Synchronization blocks are synchronized on an object in Java. All synchronized blocks that are synchronized on an object can only be entered by one thread at a time and perform operations. All other threads waiting to enter the synchronization block will be blocked until the thread that executes the synchronization block exits.
There are four different types of synchronization blocks:

1. 实例方法2. 静态方法3. 实例方法中的同步块4. 静态方法中的同步块

The above synchronization blocks are synchronized on different objects. The actual need for that synchronization block depends on the specific situation.
Instance method synchronization
The following is a synchronous instance method:

public synchronized void add(int value){ this.count += value; }
    • 1
    • 2
    • 3
    • 4
    • 1
    • 2
    • 3
    • 4

Note the Synchronize (synchronized) keyword in the method declaration. This tells Java that the method is synchronous.
The Java instance method synchronization is synchronous on the object that owns the method. In this way, each instance's method synchronization is synchronized on a different object, that is, the instance to which the method belongs. Only one thread can run in the instance method synchronization block. If more than one instance exists, a thread can perform operations in one instance synchronization block at a time. One instance of a thread.

static method Synchronization
Static method synchronization, like the instance method synchronization method, also uses the Synchronized keyword. The Java static method synchronizes the following example:

public static synchronized void add(int value){ count += value; }
    • 1
    • 2
    • 3
    • 1
    • 2
    • 3

Again, the Synchronized keyword here tells Java that this method is synchronous.
Synchronization of static methods refers to synchronizing on the class object on which the method resides. Because a class can only correspond to one class object in a Java virtual machine, it allows only one thread to execute a static synchronization method in the same class.
For static synchronization methods in different classes, a thread can execute a static synchronization method in each class without waiting. A class can be executed by only one thread at a time, regardless of whether the static synchronization method in the class is called.

Synchronization blocks in an instance method
Sometimes you don't need to synchronize the entire method, but rather part of the synchronization method. Java can synchronize part of a method.
The example of a synchronization block in a non-synchronized Java method is as follows:

public void add(int value){   synchronized(this){ this.count += value; } }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

The example uses the Java synchronization block builder to mark a piece of code as synchronous. The code is executed at the same time as the synchronization method.
Note the Java synchronization block constructor encloses the object with parentheses. In the example above, "This" is used, which is called the instance itself of the Add method. Objects enclosed in parentheses in the synchronization constructor are called Monitor objects. The code above uses the monitor object to synchronize, and the synchronous instance method uses the instance of the calling method itself as the monitor object.
Only one thread at a time can execute within a Java method synchronized to the same monitor object.
The following two examples all synchronize the instance objects they invoke, so they are equivalent to the execution effect of the synchronization.

public class MyClass {  public synchronized void log1(String msg1, String msg2){ log.writeln(msg1); log.writeln(msg2); } public void log2(String msg1, String msg2){ synchronized(this){ log.writeln(msg1); log.writeln(msg2); } } }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

In the example above, only one thread can execute within any one of the two synchronization blocks at a time.
If the second synchronization block is not synchronized on the this instance object, then two methods can be executed concurrently by the thread.
Synchronization blocks in a static method
Similar to the above, here are two examples of static method synchronization. These methods are synchronized on the class object to which the method belongs.

 public class myclass {public static synchronized void log1 (string msg1, String msg2) {Log.writeln (MSG1); Log.writeln (MSG2);} Span class= "Hljs-keyword" >public static void log2 (string msg1, String msg2) {synchronized (myclass.class) {Log.writeln ( MSG1); Log.writeln (MSG2); } } }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

These two methods do not allow simultaneous access by threads.
If the second synchronization block is not synchronized on the Myclass.class object. Then both methods can be accessed by the thread at the same time.

Use the synchronization method for some attention to detail:

1, the purpose of thread synchronization is to protect multiple threads to ask a resource when the destruction of resources.
2, thread synchronization method is implemented by the lock, each object has a cut only a lock, the lock with a specific object, the thread once the object lock, the other access to the object's thread can no longer access the object's other synchronization methods.
3, for the static synchronization method, the lock is for this class, the lock object is the class object. Static and non-static methods of locking do not interfere. A thread acquires the lock, which is obtained when a synchronization method on another object is accessed in a synchronous method.
4, for synchronization, to be awake at all times on which object synchronization, this is the key.
5, write thread-safe classes, you need to pay attention to multiple threads competing access to the logic and security of the resources to make the right judgment, the "atomic" operation to make an analysis, and ensure that other threads during atomic operation can not access the competing resources.
6. When multiple threads wait for an object lock, the thread that does not acquire the lock will block.
7, deadlock is between the threads waiting for lock-lock caused by, in practice, the probability of occurring is very small.

Lock mechanism:

Prior to Java 5.0, there were only synchronized and volatile mechanisms available to coordinate access to object sharing. Java 5.0 adds a new mechanism, reentrantlock. Contrary to the previously mentioned mechanism, Reentrantlock is not an alternative to the built-in locking method, but is an optional advanced feature when the built-in locking mechanism is not applicable.

Lock  接口的源码:
public interface Lock {    void lock(); void lockInterruptibly() throws InterruptedException; boolean tryLock(); boolean tryLock( long time, TimeUnit unit) throws InterruptedException; void unlock(); Condition newCondition();}
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

Unlike the built-in locking mechanism, the lock interface provides an unconditional, polling, timed, and interruptible lock acquisition mechanism, all locking and unlocking methods are displayed, and in lock implementations must provide the same memory visibility semantics as the internal lock, but in the lock semantics, scheduling algorithm, Sequential warranties and performance characteristics can vary.

The Reentrantlock implements the lock interface and provides the same mutex and memory visibility as the synchronized.

public class Reentrantlockextends objectimplements Lock, Serializable

Like synchronized, Reentrantlock also provides reentrant locking semantics, which provides greater flexibility in handling lock mechanism availability issues compared to synchronized.

Why create a new locking mechanism so similar to built-in locks?

In most cases, built-in locks work well, but there are some limitations in functionality, such as the inability to provide interrupts for a thread that is waiting to acquire a lock, or the ability to wait indefinitely while the request acquires a lock. The built-in lock must be freed in the code that acquires the lock, which simplifies coding (and interacts well with exception handling), but does not implement locking rules for nonblocking structures.

The standard form of using the lock interface is as follows:

class X {   private final ReentrantLock lock = new ReentrantLock();   // ...   public void m() { lock.lock(); // block until condition holds try { // ... method body } finally { lock.unlock() } } }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

Note that the lock must be released in Finally, because if an exception occurs in the try and there is no release of the lock in finally, the lock will never be freed. It is also necessary to consider the case of throwing an exception in a try, which would require more Try-catch or try-finally code if the object could be in some inconsistent state.

Polling and timing locks

The timing and polling lock acquisition mode is implemented by the Trylock method, which has a more perfect error recovery mechanism than the unconditional lock acquisition mode.
Polling Lock:

Use Trylock to get two locks, and if you can't get them at the same time, rewind and try again.

 PublicBooleanTransferMoney (account Fromacct, account Toacct, Dollaramount Amo UntLong timeout, timeunit unit)Throws Insufficientfundsexception, Interruptedexception {Long Fixeddelay = Getfixeddelaycomponentnanos (timeout, unit);Long randmod = Getrandomdelaymodulusnanos (timeout, unit);Long stoptime = System.nanotime () + Unit.tonanos (timeout);while (True) {if (FromAcct.lock.tryLock ()) {try { if (ToAcct.lock.tryLock ()) {try { if (Fromacct.getbalance (). CompareTo (amount) < 0) throw new insufficientfundsexception (); else {fromacct.debit (amount); Toacct.credit (amount); return true;} finally {ToAcct.lock.unlock ();}} } finally {FromAcct.lock.unlock ();}} if (System.nanotime () < StopTime) return FALSE; Nanoseconds.sleep (Fixeddelay + rnd.nextlong ()% randmod); } }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21st
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21st
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
Timing Lock:

When you request a lock, you can set a time-out period, and if the lock is not obtained at this time, it will not continue to block but give up the task, the sample code is as follows:

public boolean trySendOnSharedLine(String message,                                    long timeout, TimeUnit unit) throws InterruptedException { long nanosToLock = unit.toNanos(timeout) - estimatedNanosToSend(message); if (!lock.tryLock(nanosToLock, NANOSECONDS)) return false; try { return sendOnSharedLine(message); } finally { lock.unlock(); } }

Java multi-threading, concurrency Series (synchronized) synchronization and locking mechanism

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.