当前位置: 首页 > news >正文

基于AQS+双向链表实现队列先进先出

学习AQS写的一个模拟案例

package com.tom.xiangyun.ch04_aqs;import com.tom.tuling.UnsafeFactory;
import sun.misc.Unsafe;import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.ReentrantLock;/*** 使用双向链表实现队列** @author 钟棋炜* @date 2023-08-22 20:52*/
public class QueueDoubleLinked {private transient volatile Node head;private transient volatile Node tail;private static final Unsafe unsafe = UnsafeFactory.getUnsafe();private static final long headOffset;private static final long tailOffset;private static final long nextOffset;private final ReentrantLock takeLock = new ReentrantLock();private final AtomicInteger count = new AtomicInteger();static {try {assert unsafe != null;headOffset = unsafe.objectFieldOffset(QueueDoubleLinked.class.getDeclaredField("head"));tailOffset = unsafe.objectFieldOffset(QueueDoubleLinked.class.getDeclaredField("tail"));nextOffset = unsafe.objectFieldOffset(Node.class.getDeclaredField("next"));} catch (Exception ex) {throw new Error(ex);}}public QueueDoubleLinked() {}private  boolean compareAndSetHead(Node update) {return unsafe.compareAndSwapObject(this, headOffset, null, update);}private boolean compareAndSetTail(Node expect, Node update) {return unsafe.compareAndSwapObject(this, tailOffset, expect, update);}//入队public String add(String element) {Node node = new Node(element);enq(node);return element;}//出队 先进public Object poll() {final AtomicInteger count = this.count;if (count.get() == 0) {return null;}Object x = null;final ReentrantLock takeLock = this.takeLock;takeLock.lock();try {if (count.get() > 0) {x = dequeue();count.getAndDecrement();}} finally {takeLock.unlock();}return x;}private Object dequeue() {Node h = head;Node first = head.next;h.next = h;head = first;Object obj = first.data;first.data = null;return obj;}private Node enq(final Node node) {//尾插法final AtomicInteger count = this.count;for (; ; ) {Node t = tail;if (t == null) {if (compareAndSetHead(new Node())) {tail = head;}} else {node.prev = t;if (compareAndSetTail(t, node)) {t.next = node;count.getAndIncrement();return t;}}}}static final class Node {Node prev;//前置节点Node next;//后置节点Object data; //存放数据public Node() {}public Node(Object data) {this.data = data;}}public static void main(String[] args) {QueueDoubleLinked queue = new QueueDoubleLinked();queue.add("tom");queue.add("no");queue.add("xx");queue.add("zz");System.out.println(queue.poll());System.out.println(queue.poll());System.out.println(queue.poll());System.out.println(queue.poll());System.out.println(queue);}
}
http://www.lryc.cn/news/135181.html

相关文章:

  • 无涯教程-Perl - time函数
  • CUDA Bug<三>当__global__函数出现里面所有输出的数组都随机赋值了
  • 甜椒叶病害识别(Python代码,pyTorch框架,深度卷积网络模型,很容易替换为其它模型,带有GUI识别界面)
  • Python爬虫——scrapy_日志信息以及日志级别
  • 微信小程序 echarts 画多个横向柱状图
  • 【二叉树】572. 另一棵树的子树
  • 220V转5V芯片三脚芯片-AH8652
  • windows系统丢失mfc120u.dll的解决方法
  • css 实现电梯导航
  • 【Spring Boot】Spring Retry减少1000 行代码讲解
  • 【数据结构OJ题】相交链表
  • 【华为OD机试】最小传输时延I【2023 B卷|200分】
  • Android13 网络 Adb 默认开启
  • Git分享-规范/建议/技巧
  • vue3文件下载功能
  • Python调用文心一言的API
  • 【计算机网络八股】计算机网络(一)
  • 记录一次arcgis engine开发版本引入问题
  • 2023年Java毕业设计怎样选题,有哪些注意事项,300道Java毕业设计题目
  • 算法-滑动窗口-串联所有单词的子串
  • 2023年7月京东美妆护肤品小样行业数据分析(京东数据挖掘)
  • 记录Taro巨坑,找不到sass类型定义文件
  • CS1988|C#无法在异步方法中使用ref,in,out类型的参数的问题
  • ubuntu开机失败——ACPI Error
  • 搭建开发环境-操作系统篇(一键搭建开发环境)
  • 人工智能AI绘画接入使用文档
  • 如何使用PyQt进行文件操作
  • 阿里云CDN加速器基本概念与购买开通
  • 2023河南萌新联赛第(六)场:河南理工大学-F 爱睡大觉的小C
  • [C++ 网络协议编程] 域名及网络地址