Java Concurrency arts (six) - the Java lock (1)

1. Lock Interface

Comparison 1.1 Lock interface and the synchronized keyword

Lock interface previously appeared, Java implement the use of synchronized keyword lock function. And after Java 1.5, Java adds Lock interface and its implementation class to implement functions similar synchronized keyword. And synchronized Implicit get / release lock is different, Lock interface to obtain / release lock is explicit (need to call Lock.lock (), Lock.unlock () method). In addition Lock interface also has to acquire the lock interrupted thread acquires the lock timeout, non-blocking attempt to acquire locks and other synchronized keyword does not have the function.

1.2 Lock use interface

    Lock lock = new ReentrantLock();
    lock.lock();
    try {
        ...
    } finally {
        lock.unlock();
    }
复制代码

1.3 Notes on using Lock interface

● Do not get locked in a try block, because if the lock acquisition process (this time not really get to lock) exception occurs, the reason will be released in the finally block lock (not get to release the locking failure also occurs).

● To release the lock in a finally block, to ensure after obtaining the lock, the lock can be released.

1.4 Lock API interface

Method name description
void lock() The current thread tries to acquire a lock
void lockInterruptibly() throws InterruptedException You can interrupt access to the lock, which can interrupt the current thread lock acquired in
boolean tryLock() Non-blocking attempt to acquire the lock, call the method returns immediately after acquiring a lock Returns true if successful, false otherwise
boolean tryLock(long time,TimeUnit unit) throws InterruptedException Timeout acquire locks
void unlock() Release the lock
Condition newCondition() Gets waiting / notification assembly and the current lock bindings, the current thread only get a lock to call the assembly await () method, calling await () method after the current thread releases the lock will be

2. queue synchronizer AbstractQueuedSynchronizer (AQS)

2.1 AQS understanding

AQS is a basic framework to build locks or other synchronization components, it uses an int member variables to represent the synchronization status, access to resources to complete the thread (usually acquire the lock thread) work queue through the built-in FIFO queue.

2.2 AQS use

In simple terms, the main use AQS is inherited by subclasses and sub-classes are defined as static inner classes recommended synchronization components. AQS synchronization component in the polymerization, using AQS synchronization semantics. (Synchronization component can be simply understood that the above-described custom lock)

2.3 Customizing Synchronization component (lock) and the relationship between the AQS

Lock is facing the user, the lock defines the interface for the user to call, shielding the implementation details of the lock. AQS oriented implementer lock, which helps simplify the implementation of the lock, the shield synchronization state management, queuing thread wake-up and wait for the underlying operating. Lock and AQS well isolated areas required for users and implementers of concern.

2.4 Method synchronizer rewritable (rewritable mean override certain methods according to their needs)

Method name description
protected boolean tryAcquire(int arg) Exclusive acquire synchronization state, to implement this method need to query synchronization status and determine if it meets expectations, if they meet with CAS is set to a new state.
protected tryRelease(int arg) Exclusive release synchronization status.
protected int tryAcquireShared(int arg) Shared acquire synchronization state, when the compliance value is greater than or equal to 0, it retrieves synchronization status success, otherwise fail.
protected boolean tryReleaseShared(int arg) Shared released synchronization status.
protected boolean isHeldExclusively() Whether the current synchronization status has been acquired in exclusive mode.

2.5 synchronous method template provided by

Method name description
void acquire(int arg) Exclusive get in sync. If the method returns will succeed, if the acquisition fails thread synchronization queue waiting to enter. In addition, the method calls the overridden tryAcquire (int arg) method.
void acquireInterruptibly(int arg) This method is void acquire (int arg) method interrupt response version. Into the synchronous queue thread can be interrupted and throws InterruptedException exception.
boolean tryAcquireNanos(int arg,long nanos) This method is void acquireInterruptibly (int arg) method timeout waiting version.
void acquireShared(int arg) Shared acquire synchronization status, and obtain exclusive main difference is more than one thread at a time can get back in sync.
void acquireSharedInterruptibly(int arg) This method is void acquireShared (int arg) method interrupt response version.
boolean tryAcquireSharedNanos(int arg,long nanos) This method is void acquireSharedInterruptibly (int arg) method timeout waiting version.
boolean release(int arg) Exclusive release synchronization status. This method will be called tryRelease (int arg) method rewritten.
boolean releaseShared(int arg) Shared released synchronization status.
Collection< Thread >getQueueThreads() Gets a collection of threads waiting on synchronized queue.

2.5 synchronizer implementation

After synchronization is designed to be based on the template design pattern, namely custom synchronization component in the static inner class inherits AQS, rewrite the specified method. The synchronizer in the template method will be custom synchronization component calls, the template method in the call overridden methods.

class Mutex implements Lock{
    //静态内部类,自定义同步器
    private static class Sync extends AbstractQueueSynchronizer{
        //是否处于占用状态
        protected boolean isHeldExclusively(){
            return getState() == 1;
        }
        //当状态为0的时候获取锁
        public boolean tryAcquire(int acquires){
            if(compareAndSetState(0,1)){
                setExclusiveOwnerThread(Thread.currentThread());
                return true;
            }
            return false;
        }
        //释放锁,将状态设置为0
        protected boolean tryRelease(int release){
            if(getState() == 0)throw new IllegalMonitorStateException();
            setExclusiveOwnerThread(null);
            setState(0);
            return true;
        }
        //返回一个Condition,每个condition都包含了一个condition队列
        Condition newCondition(){
            return new Condition();
        }
    }
    //仅需要将操作代理到Sync上即可
    private final Sync sync = new Sync();
    public void lock(){sync.acquire(1)};
    public boolean tryLock(){
        return sync.tryAcquire(1);
    }
    public void unlock(){
        sync.release(1);
    }
    public Condition newCondition(){
        return sync.newCondition();
    }
    public boolean isLocked(){
        return sync.isHeldExclusively();
    }
    public boolean hasQueuedTreads(){
        return sync.hasQueuedTreads();
    }
    public void lockInterruptibly() throws InterruptedException{
        sync.acquireInterruptibly(1);
    }
    public boolean tryLock(long timeout,TimeUnit unit) throws InterruptedException{
        return sync.tryAcquireNanos(1,unit.toNanos(timeout));
    }
}
复制代码

Guess you like

Origin juejin.im/post/5cf9bb6c51882512a675f9b0