java concurrent programming foundation - synchronization mechanism

Thread-safe sections we analyze the common problems encountered in concurrent programming, and in the end of the article mentioned how to solve concurrency problems, which referred to solve the shared variables by state synchronization mechanism has a problem.

Synchronization concept

It refers to the relative order of the synchronization mechanism between the operating program for controlling the occurrence of different threads.

  • In the shared-memory concurrency model, explicit synchronization is performed. The programmer must explicitly specify a method or a piece of code required to perform mutual exclusion between threads.
  • In concurrency model's messaging, since the transmission message before receiving the message must therefore implicit synchronization is performed.

Java concurrency uses a shared memory model, the implementation of mutual exclusion between programmers need to specify a method or display of a section of code required thread.
The purpose of synchronization : In multi-threaded programming inside, some of sensitive shared resources do not allow simultaneous access by multiple threads, this time on the use of synchronous access technology to ensure the data at any time, there is at most one thread access, in order to ensure data integrity.

java synchronization method

Broadly speaking, the synchronization mechanism java platform provides a lock, volatile keyword, final keyword, wait / notifyAll and tools that were under the contract, such as: Semaphore, Condition and so on. Here's where the common synchronization mechanisms is described:

Lock Overview

Use locks to provide protection for the shared variable, a thread access must apply the appropriate lock before sharing data. When the thread gets a lock, said to hold the thread is a thread lock, a lock can only be held by a thread. The thread holding the lock can access the shared variable protected by locks, and release the appropriate lock after the visit.
The thread holding the lock after acquiring the lock and code execution until the lock is released this time is called the critical region . Only allow access shared variables in the critical region, critical area can only be one thread execution. Specifically by the following schematic:

Exclusive lock - a lock can only be held by a thread. Namely that only one thread can execute critical sections of code.
Lock the Java platform including the realization of the internal lock --synchronized keywords and explicit lock java.concurrent.locks.Lock interface through.

synchronized

Java platform in any lock object has only one associated with it, is called a monitor (Monitor) or internal locks. This internal lock achieved by the synchronized keyword. There are three common synchronized manner as follows:

class X {
  // 修饰非静态方法
  synchronized void foo() {
    // 临界区
  }
  // 修饰静态方法
  synchronized static void bar() {
    // 临界区
  }
  // 修饰代码块
  Object obj = new Object();
  void baz() {
    synchronized(obj) {
      // 临界区
    }
  }
}  
复制代码
  1. Amend non-static method locks the current object instance this
  2. Modified static method lock is Class object of the current class
  3. Modifying the code block is locked object obj

Use synchronized must find out who he locked object is who protects shared variables yes.

synchronized principle

First, we use the example synchronized decompiling given code shown below, which marked the monitorenter and monitorexit two bytecode instruction, these two instructions require a reference to the type of parameter to indicate locking and unlocking object.

java program if synchronized explicitly specified object argument, then that reference the object; if not explicitly stated, it is determined based on synchronized instance methods or modified methods class, if you take a class method Class object as a lock object. To conclude, lock objects are divided into two categories

  • synchronized (this) as well as non-static synchronized method, then call the object itself locked
  • static modification of static methods and synchronized (xxx.class), Class object class is locked because the Class object of a class has only one, so all objects of that class share a lock.

The jvm specification, monitorenter instruction execution, the thread attempts to acquire a first reference corresponding to the object lock

  • If the object lock is not locked possession, or before changing the thread already owns the object lock, put the lock count is incremented.
  • Accordingly, when executing the object lock monitorexit instruction counter by 1, when the counter is 0, the lock is released. Other objects were locked blocked the thread may attempt to take ownership of the object lock.

Lock

After JavaSE5, package and method used to implement the interface adds Lock lock function, which provides synchronization and synchronized similar, except that the time required to display the acquiring and releasing locks, but also provide these interfaces do not have the characteristics of synchronized following table:

characteristic description
Non-blocking attempt to acquire the lock The current thread tries to acquire the lock, the lock if this moment is not acquired by another thread that holds the lock is successfully acquired, does not block waiting for the lock release
Interrupted acquire locks And synchronized different threads can acquire a lock to respond to the interrupt, when the acquired lock thread is interrupted, interrupt exception will be thrown, while the lock is released
Timeout acquire locks Interface to obtain the lock before the specified deadline, if the deadline is still unable to acquire a lock, then return

Code corresponding to the above-described characteristics:

// 支持中断的 API
void lockInterruptibly() throws InterruptedException;
// 支持超时的 API
boolean tryLock(long time, TimeUnit unit) throws InterruptedException;
// 支持非阻塞获取锁的 API
boolean tryLock();
复制代码

ReentrantLock reentrant lock

ReentrantLock is a common realization Lock interface that supports re-entry lock means that when you call the lock () method, has acquired the lock thread can call the lock () method again without being blocked. At the same time, the lock also supports equity and non-equity options when acquiring a lock. Finally, ReentrantLock is the exclusive lock, the lock at the same time allowing only one thread to access. About Equity and non-equity few notes:

  • If the absolute time, the first request for acquiring locks must first be met, then the lock is fair, the contrary is non-fair.
  • Equitable access lock is waiting for the longest time thread priority access to the lock. ReentrantLock constructor to control whether it is fair locks.
  • Under normal circumstances, guarantee a fair lock acquire a lock according to the FIFO principle, but the price is a lot of thread switching, resulting in performance degradation. Rather than the fair could lead to part of the thread starvation, but ensures greater throughput.

Note that the following common usage patterns ReentrantLock active release lock:

private final Lock rtl = new ReentrantLock();
// 获取锁
rtl.lock();  
try {
  // 临界区
} finally {
  // 保证锁能释放
  rtl.unlock();
}  
复制代码

Read-Write Lock

ReentrantLock mentioned earlier is the exclusive lock that allows only one thread at a time to access, read-write locks while at the same time can allow multiple threads to access, but access when writing thread, read all the threads and other writing thread is blocked. Read-Write Lock maintains a lock, a lock and a read-write locks, which read lock is a shared lock can be acquired simultaneously by multiple threads, and a write lock is supported rushed into the exclusive lock. Examples ReentrantReadWriteLock write lock has the following characteristics:

  • Fair Selection: ReentrantLock and similar
  • Re-entry: reentrant lock, pay special attention to the writer thread can obtain a write lock again after obtaining a write lock, but also can get a read lock.
  • Lock downgrade: Follow obtain a write lock, then release order to obtain a read lock to write lock, write lock can be downgraded to a read lock
  • Any time a thread holds a read lock, no other thread can obtain the appropriate locks to write locks. This ensures that no other thread can read a thread to update during a read shared variables
public class Cache<K, V> {
    private ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
    private ReentrantReadWriteLock.ReadLock r = rwl.readLock();
    private ReentrantReadWriteLock.WriteLock w = rwl.writeLock();
    private Map<K, V> cache = new HashMap();

    public V getKey(K key) {
        V result = null;
        r.lock();
        try {
            result = cache.get(key);
        } finally {
            r.unlock();
        }
        if (result != null) {
            return result;
        }
        w.lock();
        try {
            result = cache.get(key);
            if (result == null) {
                // db查获取value
                V v = null;
                result = v;
                putValue(key, v);
            }
        } finally {
            w.unlock();
        }
        return result;
    }
    public V putValue(K key, V value) {
        w.lock();
        try {
            return cache.put(key, value);
        }finally {
            w.unlock();
        }
    }
}
复制代码

A non-thread-safe HashMap this example implemented as a buffer, by using a read-write lock to secure the thread. Analysis code, when read operations need to obtain a read lock for the shared locks to support multiple threads simultaneously access is not blocked. In the write operation, first obtain a write lock, after obtaining a write lock, other threads to obtain read and write locks for are blocked, the lock is released only after writing, other operations can continue, this also ensures that all reads are the latest data.

Lightweight synchronization volatile

The volatile keyword is often called lightweight lock, lock their role and the role of the same place: to ensure visibility and orderliness. Specific analysis can see java memory model, which has detailed analysis.

Guess you like

Origin juejin.im/post/5d6a81d651882505a87a9ec3