手机网站做成app,出口跨境电商平台,安徽搜索引擎推广公司,湖南网站建设公司 地址磐石网络一、队列同步器AQS
1、定义
用来构建锁或者其他同步组件的基础框架#xff0c;它使用了一个int成员变量表示同步状态#xff0c;通过内置的FIFO队列来完成资源获取线程的排队工作。是实现锁的关键。
2、实现
同步器的设计是基于模板方法模式的#xff0c;也就是说#…一、队列同步器AQS
1、定义
用来构建锁或者其他同步组件的基础框架它使用了一个int成员变量表示同步状态通过内置的FIFO队列来完成资源获取线程的排队工作。是实现锁的关键。
2、实现
同步器的设计是基于模板方法模式的也就是说使用者需要继承同步器并重写指定的方法随后将同步器组合在自定义同步组件的实现中并调用同步器提供的模板方法。
主要使用方式是继承。在实现抽象方法时避免不了修改同步器的状态。需要用到同步器的三个方法getState(),setState(int newState)和compareAndSetState(int expect,int update)。推荐子类被定义为自定义同步组件的静态内部类。
同步器提供的模板方法基本上分为3类独占式获取与释放同步状态、共享式获取与释放、同步状态和查询同步队列中的等待线程情况。
3、队列同步器 AbstractQueuedSynchronized 抽象队列式的同步器AQS定义了一套多线程访问共享资源的同步器框架许多同步类实现都依赖于它如常用的ReentrantLock/Semaphore/CountDownLatch… AQS维护了一个volatile int state(代表共享资源)和一个FIFO线程等待队列多线程争用资源被阻塞时会进入此队列。 state的访问方式有三种 getState() 、setState() 、compareAndSetState() AQS定义两种资源共享方式Exclusive独占只有一个线程能执行如ReentrantLock和Share共享多个线程可同时执行如Semaphore/CountDownLatch。 不同的自定义同步器争用共享资源的方式也不同。自定义同步器在实现时只需要实现共享资源state的获取与释放方式即可至于具体线程等待队列的维护如获取资源失败入队/唤醒出队等AQS已经在顶层实现好了。自定义同步器实现时主要实现以下几种方法 isHeldExclusively():该线程是否正在独占资源。只有用到condition才需要去实现它。tryAquire(int):独占方式。尝试获取资源成功则返回true失败则返回false。tryRelease(int):独占方式。尝试释放资源成功则返回true失败则返回false。tryAcquireShared(int):共享方式。尝试获取资源。负数表示失败0表示成功但没有剩余可用资源正数表示成功且有剩余资源。tryReleaseShared(int):共享方式。尝试释放资源如果释放后允许唤醒后续等待结点返回true否则返回false。 以ReentrantLock为例state初始化为0表示未锁定状态。A线程lock()时会调用tryAcquire()独占该锁并将state1。此后其他线程再tryAcquire()时就会失败直到A线程unlock()到state0即释放锁为止其他线程才有机会获取该锁。当然释放锁之前A线程自己是可以重复获取此锁的state会累加这就是可重入的概念。但要注意获取多少次就要释放多少次这样才能保证state是能回到零态的。 再以CountDownLatch为例任务分为N个子线程去执行state为初始化为N注意N要与线程个数一致。这N个子线程是并行执行的每个子线程执行完后countDown()一次state会CAS减1。等到所有子线程都执行完后即state0会unpark()主调用线程然后主调用线程就会await()函数返回继续后余动作。 一般来说自定义同步器要么是独占方法要么是共享方式他们也只需实现tryAcquire-tryRelease、tryAcquireShared-tryReleaseShared中的一种即可。但AQS也支持自定义同步器同时实现独占和共享两种方式如ReentrantReadWriteLock。