Java concurrent programming display lock ReentrantLock and ReadWriteLock read write lock

  • 2020-04-01 03:49:06
  • OfStack

Prior to Java5.0, only synchronized(built-in locks) and volatile. Java5.0 introduced display lock ReentrantLock.

Profile already

ReentrantLock is a ReentrantLock that, unlike a built-in lock, requires the locking and unlocking shown every time it is used, and provides advanced features: fair locks, timed locks, conditional locks, polling locks, interruptible locks

The Lock interface:


  public interface Lock {
          //Blocks until a lock is obtained or interrupts
          void lock();           //Blocks until a lock is obtained or an interrupt throw exception
          void lockInterruptibly() throws InterruptedException;           //Only if the lock is available, otherwise it simply returns
          boolean tryLock();           //The lock is only acquired when it is available at the specified time, otherwise it is returned and an exception
is thrown when interrupted           boolean tryLock(long time, TimeUnit unit) throws InterruptedException;           void unlock();           //Returns a condition
bound to the lock           Condition newCondition();
  }

Use the Lock


        Lock lock = new ReentrantLock();
        lock.lock();
        try{
            //Update object state
        }finally{
            //Note here that you must have a finally code block to unlock
            //Otherwise, it is easy to cause deadlock and other active problems
            lock.unlock();
        }
 

Already features

Polling and timing locks

ReentrantLock can have flexible fault-tolerance. Many cases of deadlocks are caused by sequential locks, where different threads block while trying to acquire the lock and do not release the lock they already hold. When the tryLock() method attempts to acquire a lock, if it is already held by another thread, it is set to return immediately instead of blocking and releasing the lock it held.

fairness

The ReentrantLock constructor provides a choice between fair and non-fair (default) locks. A fair lock, in which threads acquire the lock in the order in which they make the request, is not allowed to jump the queue. On non-fair locks, however, queue jumping is allowed: when a thread makes a request to acquire a lock, if the lock is available, the thread skips the queue waiting for the thread to acquire the lock. We generally expect all locks to be unfair. Because when a lock operation is performed, fairness significantly reduces performance due to the overhead of thread suspension and thread recovery. Consider A situation where thread A holds A lock, and thread B requests the lock, so thread B is suspended; When thread A releases the lock, thread B wakes up and tries to acquire the lock again. At the same time, the C thread also requests to acquire the lock, so the C thread is likely to acquire, use, and release the lock before the B thread is fully awakened. This is a win-win situation where the time for B to acquire the lock (until B wakes up to acquire the lock) is not delayed, and C acquires the lock earlier, and throughput is improved. In most cases, the performance of non-fair locks is higher than that of fair locks.

The lock acquisition operation can be interrupted

The lockInterruptibly method is able to acquire a lock while maintaining a response to interrupts, so there is no need to create other types of non-interruptible blocking operations.

Read-write lock ReadWriteLock

The & # 8203; ReentrantLock is a standard mutex lock that can be held by at most one thread at a time. Read/write locks are different, exposing two Lock objects, one for read operations and the other for write operations.


public interface ReadWriteLock {
    /**
     * Returns the lock used for reading.
     *
     * @return the lock used for reading.
     */
    Lock readLock();     /**
     * Returns the lock used for writing.
     *
     * @return the lock used for writing.
     */
    Lock writeLock();
}

Optional implementation:

Release first
2. Read thread queue-jumping
3. The reentrant
4. The drop
5. Upgrade

ReentrantReadWriteLock implements the ReadWriteLock interface, and the constructor provides both fair and non-fair lock creation. Read-write locks are good for reading more and writing less, allowing for better concurrency.
 
The sample


public class ReadWriteMap<K, V> {
    private Map<K, V> map;
    private final ReadWriteLock lock = new ReentrantReadWriteLock();     private final Lock readLock = lock.readLock();
    private final Lock writeLock = lock.writeLock();     public ReadWriteMap(Map<K, V> map) {
        this.map = map;
    }     public V get(K key) {
        readLock.lock();
        try {
            return map.get(key);
        } finally {
            readLock.unlock();
        }
    }     public void put(K key, V value) {
        writeLock.lock();
        try {
            map.put(key, value);
        } finally {
            writeLock.unlock();
        }
    }
}


Related articles: