JDK源码03

队列同步器(AQS)

jdk版本:java11
AQS实现是通过一个int成员变量来表示同步状态,通过内置的FIFO队列来完成线程的等待工作
其实际上是一个双向链表,有tail,head,state

同步器中主要可重写的方法

方法说明
protected boolean tryAcquire(int arg)独占式的获取同步状态
protected boolean tryRelease(int arg)独占式释放同步状态
protected int tryAcquireShared(int arg)共享式获取同步状态
protected boolean tryReleaseShared(int arg)共享式释放同步状态
protected boolean isHeldExclusively()当前同步器是否被当前线程占用

支持独占的AQS应该实现tryAcquiretryRleaseisHeldExclusively方法;支持共享的AQS应该实现tryAcquireSharedtryReleaseShared方法

同步器实现

Node

node主要的属性为next,pre, thread
thread为给节点进入队列时的线程

Acquire和Release


如同以上中acquire(int)acquireShared(int)release(int)releaseShared(int)则会在其内部调用其对应的try方法

acquire

addwaiter


JDK9的时候提供变量句柄VarHandle的方式对类中的变量进行操作,compareAndSetTail就是通过设置tail的VarHandle,对tail进行操作cas操作

acquireQueue

请添加图片描述
为了维护FIFO原则,头结点释放同步状态,他的后继节点才能获取去同步状态,同样后继节点被唤醒时,必须检查其前继节点是否为头结点

acquire()执行流程

acquireShared


releaseShared

请添加图片描述

使用

1、确定访问模式:独占,共享
2、确定资源数:设置状态数量
3、组合自定义同步器:Lock+AQS
官方的例子

独占锁,同一时刻只允许有一个线程获取到锁
class Mutex implements Lock, java.io.Serializable {   
// Our internal helper class   
private static class Sync extends AbstractQueuedSynchronizer {     // Acquires the lock if state is zero     
public boolean tryAcquire(int acquires) {       
	//assert acquires == 1; 
	// Otherwise unused       
	if (compareAndSetState(0, 1)) {
         setExclusiveOwnerThread(Thread.currentThread());
         	return true;       
       	}
        return false;     
	}     
// Releases the lock by setting state to zero     
	protected boolean tryRelease(int releases) {       
		//assert releases == 1; 
		// Otherwise unused       
		if (!isHeldExclusively())         
			throw new IllegalMonitorStateException();       	
		setExclusiveOwnerThread(null);       
		setState(0);       
		return true;     
	}     
	// Reports whether in locked state     
	public boolean isLocked() {
	       return getState() != 0;
    }     
    public boolean isHeldExclusively() {       
    	// a data race, but safe due to out-of-thin-air guarantees
     	return getExclusiveOwnerThread() ==Thread.currentThread();
     }     
     // Provides a Condition     
     public Condition newCondition() {       
     	return new ConditionObject();     
     }   
}   
     // 将操作代理到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.isLocked(); }
   public boolean isHeldByCurrentThread() {
     return sync.isHeldExclusively();
   }
   public boolean hasQueuedThreads() {
     return sync.hasQueuedThreads();
   }
   public void lockInterruptibly() throws InterruptedException {
     sync.acquireInterruptibly(1);
   }
   public boolean tryLock(long timeout, TimeUnit unit)
       throws InterruptedException {
     return sync.tryAcquireNanos(1, unit.toNanos(timeout));
   }

参考资料

《Java并发编程的艺术》
《Java并发编程实践》

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值