亲宝软件园·资讯

展开

Java 基于AQS实现自定义同步器 Java 基于AQS实现自定义同步器的示例

心悦君兮君不知-睿 人气:0
想了解Java 基于AQS实现自定义同步器的示例的相关内容吗,心悦君兮君不知-睿在本文为您仔细讲解Java 基于AQS实现自定义同步器的相关知识和一些Code实例,欢迎阅读和指正,我们先划重点:Java,AQS,Java,自定义同步器,下面大家一起来学习吧。

一、AQS-条件变量的支持

在如下代码中,当另外一个线程调用条件变量的signal方法的时候(必须先调用锁的lock方法获取锁),在内部会把条件队列里面队头的一个线程节点从条件队列里面移除并且放入AQS的阻塞队列里面,然后激活这个线程。

public final void signal() {
 if(!isHeldExclusively()) {
  throw IllegalMonitorException();
 }
 Node first = firstWaiter;
 if(first != null){
  // 将条件队列头元素移动到AQS队列
  doSignal(first);
 }
}
private Node addConditionWaiter() {
 Node t = lastWaiter;
 ...
 // (1)
 Node node = new Node(Thread.currentThread(),Node.CONDITION);
 // (2)
 if(t == null){
  firstWaiter = node;
 }else {
  t.nextWaiter = node; // (3)
 }
 lastWaiter = node; // (4)
 return node;
}

二、基于AQS实现自定义同步器

package com.ruigege.LockSourceAnalysis6;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;

public class NonReentrantLockME implements Lock,java.io.Serializable{
 // 内部帮助类
 private static class Sync extends AbstractQueueSynchronizer {
  // 是否锁已经被持有
  protected boolean isHeldExclusively() {
   return getState() == 1;
  }
  
  // 如果state为0,则尝试获取锁
  public boolean tryAcquire(int acquires) {
   assert acquires == 1;
   if(compareAndSetState(0,1)) {
    setExclusiveOwnerThread(Thread.currentThread());
    return true;
   }
   return false;
  }
  
  // 尝试释放锁,设置state为0
  protected boolean tryRelease(int release) {
   assert releases == 1;
   if(getState() == 0) {
    throw new IllegalMonitorStateException();
   }
   setExclusiveOwnerThread(null);
   setState(0);
   return true;
  }
  
  // 提供条件变量接口
  Condition newConditon() {
   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.newConditon();
 }
 
 public boolean isLocked() {
  return sync.isHeldExclusively();
 }
 
 public void lockInterruptibly() throws InterruptedException {
  sync.acquireInterruptibly(1);
 }

 public boolean tryLock(long timeout,TimeUnit unit) throws InterruptedException {
  return sync.tryAcquireNanos(1,unit.toNanos(timeout));
 }
}

如上面的代码,NonReentrantLock定义了一个内部类Sync用来实现具体的锁的操作,Sync则继承了AQS ,由于我们实现的独占模式的锁,所以Sync重写了tryAcquire\tryRelease和isHeldExclusively3个方法,另外Sync提供了newCondition这个方法用来支持条件变量。

三、源码:

所在包:com.ruigege.ConcurrentListSouceCodeAnalysis5

https://github.com/ruigege66/ConcurrentJava

加载全部内容

相关教程
猜你喜欢
用户评论