首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

数据结构界的三大幻神----队列

队列的基本操作包括入队(Enqueue)和出队(Dequeue)。入队就是将元素添加到队列尾部,出队则是从队列的头部取出元素。...队列很多实际场景中都有应用,比如消息队列、任务队列、乘客排队等。它的优势在于能够高效地进行入队和出队操作,而且入队和出队的时间复杂度都是 O(1)。...实现队列时,可以使用数组或链表来存储元素。使用数组实现的队列称为顺序队列,而使用链表实现的队列称为链式队列。 例如,多线程编程中,任务队列可以用于协调线程之间的工作分配。...就像在排队时,先到的人先得到服务。 队列可以想象成一个管子,元素从一端进入,另一端出去。新元素被添加到队列尾部,而从队列中取出元素时,总是从头部开始。...处理完成后任务入队:线程完成任务处理后,可以将结果或其他相关信息重新入队,以便其他线程可以获取和处理。

12110

AQS源码分析

,一直自旋去尝试获取同步等待状态图片AQS 通过内置的 FIFO 同步双向队列来完成资源获取线程的排队工作,内部通过节点 head【实际上是虚拟节点,真正的第一个线程 head.next 的位置】和...(Thread) 去停止阻塞它们的实质都是通过 UnSafe 类使用了 CPU 的原语 AQS 中使用 park 的主要作用是,让排队的线程阻塞掉(停止其自旋,自旋会消耗 CPU 资源)并在需要的时候...的方式来进行 CAS 操作如果直接拿头节点属性的话,没有办法直接使用 CAS可以完成线程安全的操作从 JDK9 之后增加的内容是第一个节点,初始化头部队列尾部队列,两个是同一个由于是多线程同时进行加锁...,所以要考虑线程安全如果直接锁定整个链表的话,锁的粒度就比较大,这里面加锁采用的是 CAS 加锁的方式使用 CAS 保证入队安全,获取原来的 tail,修改前进对比,看看是不是原来那个了,如果不是重新获取...图片图片图片图片获取到线程中断后,直接抛出一个异常,取消线程的竞争,设置状态为 NODE.CANCELLED 状态,把节点从队列当中移除,重新建立前后节点,获取前驱节点 cancelAcquire(node

21310
您找到你想要的搜索结果了吗?
是的
没有找到

使用JavaScript创建队列结构

队列和栈是两种相似的结构,区别主要在于栈是先进后出,队列是先进先出(FIFO)。队列插入元素是队尾插入,队列头弹出,形象的描述为排队,先到的先办事,后到的后办事。...算法应用上可以应用在消息队列、的打印机队列等。...(element):向队列尾部添加一个或多个新的元素 dequeue():从队列顶部移除元素并返回 front():返回队列顶部元素,不对队列做任何操作 isEmpty():判断队列是否是空队列,是返回...> 1){ for (var i=0; i<num; i++){ queue.enqueue(queue.dequeue()); //将从头部移除并获取到的元素重新压入队列...,存储队列尾部 } eliminated = queue.dequeue();//从头部移除并获取,此人是被淘汰的人 console.log(eliminated

84050

Java 并发(4)AbstractQueuedSynchronizer 源码分析之条件队列

,这两个排队区分别是同步队列和条件队列。...我们还是拿公共厕所做比喻,同步队列是主要的排队区,如果公共厕所没开放,所有想要进入厕所的人都得在这里排队。...(进入条件队列等待),当然在出去之前还得把锁给释放了好让其他人能够进来,准备好了手纸 (条件满足) 之后它又得重新回到同步队列中去排队。...当然进入房间的人并不都是因为没带手纸,可能还有其他一些原因必须中断操作先去条件队列中去排队,所以条件队列可以有多个,依不同的等待条件而设置不同的条件队列。...注意,这个过程只是将结点添加到同步队列尾部而没有挂起线程哦。

40520

Java并发包下锁学习第三篇-锁是怎么维护内部队列

我们知道AQS能够通过内置的FIFO队列来完成资源获取线程的排队工作。那么AQS是怎么来维护这个排队工作的呢?今天我们就来扒一扒AQS源码。从源码中来看看是怎么维护对了的。...这个对象就是来维护线程对资源访问的排队工作的。具体怎么操作的呢?本文主要内容:Node节点介绍;同步器中怎么为维护排队的流程图。 一:Node节点对象介绍 AQS内部有个Node对象的内部类。...等待condition通知。也可以理解成condition队列中。 static final int PROPAGATE = -3:共享模式下,下一次无条件传播 0:默认状态。...其他线无非获取到资源的线程会被构成成Node节点对象并被放到队列中。被构造成Node节点的线程会排在队列尾部排队。...被设置尾部的Node节点的next将指向头节点。 如上图中线程3会和线程1执行类似的操作,把自己添加到队列尾部。这样就形成了一个完整的双向队列排队了。

20020

从 0 开始学习 JavaScript 数据结构与算法(四)队列

认识队列 队列(Queue)是一种运算受限的线性表,特点:先进先出。(FIFO:First In First Out) 受限之处: 只允许表的前端(front)进行删除操作。...只允许表的后端(rear)进行插入操作。 生活中类似队列结构的场景: 排队,比如在电影院,商场,甚至是厕所排队。 优先排队的人,优先处理。(买票、结账、WC)。 ? image 队列图解 ?...image 队列程序中的应用 打印队列:计算机打印多个文件的时候,需要排队打印。 线程队列:当开启多线程时,当新开启的线程所需的资源不足时就先放入线程队列,等待 CPU 处理。...队列的实现 队列的实现和栈一样,有两种方案: 基于数组实现。 基于链表实现。 队列常见的操作 enqueue(element) 向队列尾部添加一个(或多个)新的项。...(let i = 0; i < number - 1; i++) { // number 数字之前的人重新放入到队尾(即把队头删除的元素,重新加入到队列中) queue.enqueue

41430

听说Mutex源码是出名的不好看,我不信,来试一下

加入spin机制 这就好比上厕所一样,你排了好久队,好不容易排到了第一位可以去抢厕所了,由于厕所被锁了,不得不重新排队,是不是有点蛋疼。...自旋不是无限制的,协程旋转几圈后,如果还没抢到锁,那它只能乖乖去队列尾部排队了。...这次改进中,还修复了被唤醒的协程需重新去队尾排队的问题:如果协程被唤醒后抢锁失败,会被放到队列头部等待唤醒。...,排队的话需要看排队到头部还是尾部 if atomic.CompareAndSwapInt32(&m.state, old, new) { // 这里还需要看一下 // 如果原来的old...// queueLifo 为false,表示是第一次排队排队时排到队列尾部 queueLifo := waitStartTime !

34910

【久远讲算法6】队列——先进先出的数据结构

新元素从尾部进入队列,然后一直向前移动到头部,直到成为下一个被移除的元素。最新添加的元素必须在队列尾部等待,队列中时间最长的元素则排在最前面。...队列字如其名,它的例子在生活中也是比比皆是的,我们现实中的排队即为队列的应用。 日常生活中,我们进电影院要排队超市结账要排队,好的队列只允许一头进,另一头出,不可能发生插队或者中途离开的情况。...Queue() :创建一个空队列。它不需要参数,且会返回一个空队列。 enqueue( item ) :队列尾部添加一个元素。它需要一个元素作为参数,不返回任何值。...既然要创建队列,我们首先要确认队列的头尾,在这里我们假设队列尾部列表的位置 0 处。...只需要掌握列表的一些要点,就可以轻松的将队列和栈实现,我们基础篇只讲解了最基础的实现方法,在后续的提高篇里会告诉大家考试或者就业面试中,站和队列要怎么运用。

62300

「编程架构实战」——Java并发包基石-AQS详解

AQS维护两个指针,分别指向队列头部head和尾部tail。  其实就是个双端双向链表。...true,意味着获取同步状态成功,后面的逻辑不再执行;若返回false,也就是获取同步状态失败,进入b步骤; b.此时,获取同步状态失败,构造独占式同步结点,通过addWatiter将此结点添加到同步队列尾部...(此时可能会有多个线程结点试图加入同步队列尾部,需要以线程安全的方 式添加); c.该结点以队列中尝试获取同步状态,若获取不到,则阻塞结点线程,直到被前驱结点唤醒或者被中断。...addWaiter  为获取同步状态失败的线程,构造成一个Node结点,添加到同步队列尾部  先cas快速设置,若失败,进入enq方法 将结点添加到同步队列尾部这个操作,同时可能会有多个线程尝试添加到尾部...(或共享式或独占式)加入到同步队列尾部(采用自旋CAS来保证此操作的线程安全),随后线程会阻塞;释放时唤醒头结点的后继结点,使其加入对同步状态的争夺中。

38800

JS 中实现队列操作可以很简单

在这篇文章中,我将描述队列数据结构,它有哪些操作,并提供一个JavaScript的队列实现。 1. 队列数据结构 想象一下,如果你喜欢旅行(像我一样),你很可能已经机场办理了登机手续。...一名旅客刚进入机场,想要办理登机手续,他将会排队等候。另一个刚刚通过值机手续的旅客将从队列中退出。 这是队列的真实示例—队列数据结构以同样的方式工作。 队列是一种先输入先输出(FIFO)数据结构。...第一个进入队列的项(输入)是第一个退出队列的项(输出)。 一个队列有两个指针:头和尾。最早进入队列的项队列的头部,而最新进入队列的项队列尾部。...队列的操作 该队列支持2个主要操作:入队列和出队列。此外,您可能会发现使用peek和length操作很有用。 2.1 入队操作 入队操作队列尾部插入一项。进入队列的项成为队列尾部。...上图中的排队操作将项目8插入到尾部。8成为队列尾部。 queue.enqueue(8); 2.2 出队操作 出队列操作提取队列头部的项。队列中的下一项成为头部。

1.6K20

【数据结构与算法】详解什么是队列,并用代码手动实现一个队列结构

我们先用一个形象的例子来了解一下队列的定义 我们可以把队列想象成我们排队买票的队伍,每个排队的人就相当于一个元素 ?...紧接着后面又来了一个人,也要排队买票,但按照排队的规则,这个新来的人只能排在上一个人的后面,所以此时的队伍是这样的 ?...所以我们总结的来说一下,队列就是一个受限的线性表,遵循着“先进先出,后进后出”的原则,即只允许队列的前端删除元素,队列的后端进行添加元素。...三、用代码实现一个队列结构 接下来,我们就用JavaScript实现一个基于数组的线性结构的类,因为是基于数组实现的队列,所以我们可以把数组的头部看作是队列的前端,把数组的尾部看作是队列的后端 (1)...其实很简单,因为所有人坐成一个圈形成了一个循环,所以我们可以每数一个数,将队列前端的元素取出,再重新添加到队列的后端,如果是数到了刚开始规定的数字,则该被取出的元素不再被添加到队列的后端了,然后又继续重新数数

28720

【编程架构实战】——Java并发包基石-AQS详解

本章我们就一起探究下这个神奇的东东,并对其实现原理进行剖析理解 基本实现原理 AQS使用一个int成员变量来表示同步状态,通过内置的FIFO队列来完成获取资源线程的排队工作。     ...AQS维护两个指针,分别指向队列头部head和尾部tail。  其实就是个双端双向链表。...(此时可能会有多个线程结点试图加入同步队列尾部,需要以线程安全的方 式添加); c.该结点以队列中尝试获取同步状态,若获取不到,则阻塞结点线程,直到被前驱结点唤醒或者被中断。...addWaiter  为获取同步状态失败的线程,构造成一个Node结点,添加到同步队列尾部  先cas快速设置,若失败,进入enq方法 将结点添加到同步队列尾部这个操作,同时可能会有多个线程尝试添加到尾部...(或共享式或独占式)加入到同步队列尾部(采用自旋CAS来保证此操作的线程安全),随后线程会阻塞;释放时唤醒头结点的后继结点,使其加入对同步状态的争夺中。

41700

怒肝 JavaScript 数据结构 — 双端队列

队列的规则是尾部添加新元素,从头部移除最近的元素。 我们还举了一个排队的例子。比如你去买早点,看到前面有人,你肯定要从最后面排队,排在最前面的人先买到早点,然后才能轮到下一个人。...这就相当于队列中,又发生了栈的“后进先出”的情况。 其实这就是双端队列,双端队列约等于 队列+栈。...现在我们看具体的概念:双端队列,英文名 deque,是一种允许我们同时从头部和尾部添加和移除元素的特殊队列。可以把它看作是队列和栈相结合的一种数据结构。 双端队列计算机世界里最常见的应用是——撤销。...但是你突然发现有个字写错了,此时是可以键盘上用 ctrl+z 撤销的,这个撤销操作就是把最后面的文字从队列尾部出列,表示这个文字被移除了。...情况一:队列为空 如果队列为空,则从队列的头部和尾部插入元素是一样的。所以这种情况我们直接调用从尾部插入元素的方法即可。

14420

队列

队列是一个有序列表,遵循先入先出的原则。即先存入队列的数据,要先取出。后存入的要后取出。可以用数组或是链表来实现。队列最形象的比喻是:公车排队问题,先排队的要先上车,后排队的后上车。...private int rear; // 队列尾 private int[] arr; // 数组用于存放数据,模拟队列 /** * 创建队列的构造器 *...,最大下标是maxSize-1 front = -1; // 指向队列的头部,初始值是-1,每次取出数据的时候先+1 rear = -1; // 指向队列尾部,初始值为...{ return rear == maxSize - 1; // rear指向队列尾部,与队列的最大下标(maxSize - 1)相比,相等则是队列已经满了 } /*...* * @param n */ public void addQueue(int n) { if (isFull()) { // 添加数据队列前要判断是是否队列满了

43920

【Day32】LeetCode刷刷刷。

所有三明治都放在一个 栈 里,每一轮: 如果队列最前面的学生 喜欢 栈顶的三明治,那么会 拿走它 并离开队列。 否则,这名学生会 放弃这个三明治 并回到队列尾部。...解题思路: 从题目中,我们可以知道,三文治的数量与排队学生的数量是相等的,当队伍中的学生遇到喜欢吃的三文治,会取走并离开队伍,离开就代表元素从数组中删除,排队的学生存放在数组中,我们不方便执行删除操作...为了模拟题目中排队的情形,我们同时遍历三文治数组 与 学生集合,会有两种情况: 当遍历到的两个元素相等(学生遇到喜欢吃的三文治),这时候我们将学生元素从集合中删除,List集合使用remove()方法删除元素后...因为没有遇到喜欢三文治的学生会回到队尾继续排队,所以我们需要在学生集合遍历到尾部时进行判断,判断也会遇到两种情况: 当这一轮遍历过程中,所有队伍中所有学生都没有遇到喜欢的三文治,即学生集合中没有与当前位置三文治数组元素相等的元素...//标记恢复默认false st = 0; //学生集合下标归0,遍历重新排队的学生

21740

【编程架构实战】——Java并发包基石-AQS详解

本章我们就一起探究下这个神奇的东东,并对其实现原理进行剖析理解 基本实现原理 AQS使用一个int成员变量来表示同步状态,通过内置的FIFO队列来完成获取资源线程的排队工作。     ...AQS维护两个指针,分别指向队列头部head和尾部tail。  其实就是个双端双向链表。...(此时可能会有多个线程结点试图加入同步队列尾部,需要以线程安全的方 式添加); c.该结点以队列中尝试获取同步状态,若获取不到,则阻塞结点线程,直到被前驱结点唤醒或者被中断。...addWaiter  为获取同步状态失败的线程,构造成一个Node结点,添加到同步队列尾部  先cas快速设置,若失败,进入enq方法 将结点添加到同步队列尾部这个操作,同时可能会有多个线程尝试添加到尾部...(或共享式或独占式)加入到同步队列尾部(采用自旋CAS来保证此操作的线程安全),随后线程会阻塞;释放时唤醒头结点的后继结点,使其加入对同步状态的争夺中。

34300

concurrent包下线程池类小结

一个由数组支持的有界阻塞队列。此队列按 FIFO(先进先出)原则对元素进行排序。队列的头部是队列中存在时间最长的元素。队列尾部队列中存在时间最短的元素。...新元素插入到队列尾部队列获取操作则是从队列头部开始获得元素。类图如下图所示。...创建并返回“包装的”ExecutorService 方法,它通过使特定于实现的方法不可访问来禁用重新配置。 创建并返回 ThreadFactory 的方法,它可将新创建的线程设置为已知的状态。...大多数情况下,核心和最大池大小仅基于构造来设置,不过也可以使用setCorePoolSize(int)和 setMaximumPoolSize(int)进行动态更改。...可以使用此队列与池大小进行交互: 如果运行的线程少于corePoolSize,则Executor始终首选添加新的线程,而不进行排队

57940
领券