怎么在Java中利用AQS实现一个自定义同步器

发布时间:2021-03-01 15:04:55 作者:戴恩恩
来源:亿速云 阅读:256

这篇文章主要为大家详细介绍了怎么在Java中利用AQS实现一个自定义同步器,文中示例代码介绍的非常详细,具有一定的参考价值,发现的小伙伴们可以参考一下:

Java的特点有哪些

Java的特点有哪些 1.Java语言作为静态面向对象编程语言的代表,实现了面向对象理论,允许程序员以优雅的思维方式进行复杂的编程。 2.Java具有简单性、面向对象、分布式、安全性、平台独立与可移植性、动态性等特点。 3.使用Java可以编写桌面应用程序、Web应用程序、分布式系统和嵌入式系统应用程序等。

一、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;
}

怎么在Java中利用AQS实现一个自定义同步器

二、基于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这个方法用来支持条件变量。

以上就是亿速云小编为大家收集整理的怎么在Java中利用AQS实现一个自定义同步器,如何觉得亿速云网站的内容还不错,欢迎将亿速云网站推荐给身边好友。

推荐阅读:
  1. AbstractQueuedSynchroizer(AQS) 同步器详解详解
  2. JAVA中如何实现AQS

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

java aqs

上一篇:如何在Python中利用Turtle模块绘制一个国旗

下一篇:怎么在Python中利用Selenium对Cookie进行操作

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》