El sincronizador de cola AbstractQueuedSynchronizer (AQS) es la clave para implementar varios bloqueos. Por lo tanto, si desea desbloquear el principio o implementar el bloqueo usted mismo, primero debe comprender AQS.
API
Varios métodos para obtener y modificar el estado de AQS
- protected final int getState(): Obtener el estado de sincronización
- protected final void setState(int newState): Establece el estado de sincronización
- booleano final protegido compareAndSetState (int expect, int update): estado de sincronización del conjunto atómico
En tercer lugar, si el estado original es igual al esperado, se cambia al estado de actualización; de lo contrario, devuelve falso
métodos que pueden ser anulados
- Protegido booleano tryAcquire(int arg): Obtener el estado de sincronización exclusivamente.En este método, debe consultar el estado actual y determinar si es el esperado, y luego CAS establece el estado de sincronización
- protected boolean tryRelease(int arg): el estado de sincronización se libera exclusivamente, y el subproceso que espera obtener el estado de sincronización tiene la oportunidad de obtener el estado de sincronización
- protected int tryAcquireShared(int arg): estado de sincronización de adquisición compartida, devuelve >=0 para indicar una adquisición exitosa; de lo contrario, indica una falla de adquisición
- Protegido booleano tryReleaseShared(int arg): estado de sincronización de lanzamiento compartido
- protected boolean isHeldExclusively(): si el sincronizador actual está ocupado por un subproceso en modo exclusivo
Métodos de plantilla proporcionados por AQS
- public final void adquirir (int arg): adquiere exclusivamente el estado de sincronización y regresa si la adquisición es exitosa; de lo contrario, ingresa a la cola de sincronización y espera, y se llamará a tryAcquire (int arg) reescrito.
- public final void adquirir Interruptiblemente (int arg): Exclusivo es adquirir el estado de sincronización, pero puede responder a interrupciones y lanzar excepciones cuando se interrumpe
- public final boolean tryAcquireNanos(int arg, long nanosTimeout):独占是获取同步状态,能响应中断,且有超时,超时返回false
- public final void acquireShared(int arg):共享式获取同步状态,没获取到则进入同步队列,同一时刻可以有多个线程获取到同步状态
- public final void acquireSharedInterruptibly(int arg):可以被中断
- public final boolean tryAcquireSharedNanos(int arg, long nanosTimeout):带超时,且能被中断
- public final boolean release(int arg):独占式释放同步状态,释放后会将同步队列第一个节点唤醒
- public final boolean releaseShared(int arg): 共享式释放同步状态;
- public final Collection getQueuedThreads(): 获取同步队列里的线程
一些说明:
- 1.可以把AQS理解为管理状态的一个东西,然后你可以通过重写他的一些方法定义自己的规则
- 2.共享式:指几个线程可以同时获得同步状态,独占式:指只能单独的线程获得同步状态
- 3.方法比较多,不要怕,通过下边的例子和之后对一些锁的实现原理分析就能理解了
AQS实现独占不可重入锁
LockTest内部结构
方法使用全部可以上面API部分找到
编写锁
同步器编写
锁的方法重写
测试
public static void main(String[] args) {
Lock lock = new NotReentrantLock();
//线程1
new Thread(() -> {
lock.lock();
try {
for (int i = 0; i < 30; i++) {
System.out.println(Thread.currentThread().getName() + "--" + i);
Thread.sleep(2000);
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}).start();
new Thread(() -> {
lock.lock();
try {
for (int i = 0; i < 30; i++) {
System.out.println(Thread.currentThread().getName() + "--" + i);
}
} finally {
lock.unlock();
}
}).start();
}
复制代码