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

手写一个阻塞队列

每次弹出都是队列第一个元素,而插入元素则会被添加到队尾,当下标到达末尾时会被设置0。从数组一个下标重新开始向后增长,形成一个不断循环过程。...接着我们来看看队列构造器,在构造器中主要就是实例化一个大小capacity数组并且将 takeIndex ,putIndex和count值都设置0。...并且putIndex向后移动一位,如果已经到达末尾则会返回队列开头。count会加1。然后,唤醒其他等待线程进行消费。...当count==0时表示队列为空。当前线程进入等待队列,并且释放锁。然后取出takeIndex指向位置中元素,并将该位置清空。然后takeIndex向后移动一位,如果已经到达末尾则会返回队列开头。...我们可以使用一个while循环来包裹this.wait()调用和对count条件判断达到目的。 测试队列 如下,创建了一个大小4阻塞队列,然后创建四个线程,两个生产者线程,两个消费者线程。

78030

关于Java集合小抄

节约空间,但数组有容量限制。超出限制时会增加50%容量,用System.arraycopy()复制到新数组,因此最好能给出数组大小预估值。默认第一次插入元素时创建大小10数组。...取模用位运算(hash & (arrayLength-1))会比较快,所以数组大小永远是2N次方, 你随便给一个初始值比如17会转为32。默认第一次放入元素时初始值是16。...它是唯一一个允许放入nullQueue。 ArrayDeque 以循环数组实现双向Queue。大小是2倍数,默认是16。...普通数组只能快速在末尾添加元素,为了支持FIFO,从数组头快速取出元素,就需要使用循环数组:有队头队尾两个下标:弹出元素时,队头下标递增;加入元素时,如果已到数组空间末尾,则将元素循环赋值到数组[0]...元素需实现Delayed接口,每次调用时需返回当前离触发时间还有多久,小于0表示该触发了。 pull()时会用peek()查看队头元素,检查是否到达触发时间。

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

面试系列之-HashMap实现原理(JAVA基础)

这个0.75就是默认负载因子,可由构造传入;也可以设置大于1负载因子,这样数组不会扩充,牺牲性能,节省内存; 为了解决碰撞,数组元素是单向链表类型。...,还会先检测当前数组是否到达一个阈值(64),如果没有到达这个容量,会放弃转换,先去扩充数组;所以上面也说了链表长度阈值是7或8,因为会有一次放弃转换操作; HashMap中put()和get()...此时,就会拿着k和链表上每个节点k进行equal;如果所有的equals方法返回都是false,那么这个节点将被添加到链表末尾;如其中有一个equals返回了true,那么这个节点value将会被覆盖...:将元素 hashCode() 和自己右移 16 位后结果求异或; HashMap为什么允许key/valuenull,但最多只有一个 如果keynull会放在第一个bucket(即下标0)位置...并发时候原来顺序被另外一个线程a颠倒,而被挂起线程b恢复后拿扩容前节点和顺序继续完成第一次循环后,又遵循a线程扩容后链表顺序重新排列链表中顺序,最终形成了环。

1.2K21

数据结构思维 第三章 `ArrayList`

如果我们删除列表末尾元素,循环永远不会运行,这个方法是常数时间。如果我们删除第一个元素,我们遍历所有剩下元素,它们是线性。...现在数组大小是4。 第四次存储1个元素。 第五次调整数组大小,复制4个元素,并存储1个元素。现在数组大小是8。 接下来3个添加储存3个元素。 下一个添加复制8个并存储1个。现在大小是16。...这个循环是线性,除了在列表末尾添加特殊情况中。因此, add(int, E)是线性。...在这个例子中,如果我们向列表添加列表第一个元素,我们必须修改head。否则,我们遍历列表,找到末尾,并添加新节点。 此方法展示了,如何使用for循环遍历列表中节点。...该数组从不收集垃圾,并且在列表本身被销毁之前,元素不会收集垃圾。 链表实现一个优点是,当元素被删除时它会缩小,并且未使用节点可以立即被垃圾回收。

39220

【C语言】字符串函数+内存操作函数

目标字符串末尾空字符会被源字符串首字符覆盖掉,并且空字符会被包含在新连接成字符串末尾后面 1.返回类型目标字符串首地址,两个参数分别为不可改变源字符串首地址和可以改变目的地字符串地址...如果source中C字符串长度小于num,则只追加终止符null之前内容,这个函数并不会像strcpy一样去补齐空字符直到达到num个数,它追加过程中若遇到空字符,则停止追加 1.这里我们给大家看一眼...,查找下一个标记,并且再把他变成’\0‘,并且继续保存这个位置,以便下一次这个函数继续从这个位置向后找标记(当然继续向后找时,我们还是要给strtok函数第一个参数传一个NULL) 5.所以这个函数使用方式就是...,当你用大括号之后,这个字符数组末尾是没有\0了,如果没有\0的话,会让我们指针找不到停下来条件,因为它向后找呀找,想要找到\0位置,这样是有可能发生向后越界访问,导致程序出错 3...."; const char arr2[] = "hello bit"; strncpy(arr1, arr2,9); //为什么说以上三个函数是长度不受限制字符串函数,虽然arr1数组大小不够存放

89920

java基础知识之FileInputStream流

,返回读入缓冲区总字节数,若到达文件末尾,则返回-1 public int read(byte[] b) throws IOException 1....返回值53 继续往下执行发现b[0]=(byte)53.也就是将读取到int型转为字节并存储在数组第一个位置,此时数组内容[53,52] 继续执行进入for循环,此时流中已没有字节,那么read...,源码中for循环,尽管len是10(数组长度),但是当i=5时,流中字节已经读取完毕,指针移到文件末尾,因此不会继续执行for循环。...并且返回5,刚好符合结果中第一次实际读取5个字节到数组中。第二次读取时指针已到末尾。因此int c = read()这里返回-1。...个字节到字节数组中(从数组off位置开始存储字节),当len0时则返回0,如果len不为零,则该方法将阻塞,直到某些输入可用为止–此处存疑 public int read(byte[] b,int

52630

MIT 6.S081 Lab Seven -- 多线程

(gdb) b uthread.c:60 这将在uthread.c第60行设置断点。断点可能会(也可能不会)在运行uthread之前触发。为什么会出现这种情况?...由于上下文切换永远都发生在函数调用边界(swtch 调用边界),恢复执行相当于是 swtch 返回过程,会从堆栈中恢复 caller-saved 寄存器, 所以用于保存上下文 context...恢复后执行到哪里是通过 ra 寄存器来决定(swtch 末尾 ret 转跳到 ra) 而 trapframe 则不同,一个中断可能在任何地方发生,不仅仅是函数调用边界,也有可能在函数执行中途,所以恢复时候需要靠...这个实验比较简单,首先是问为什么造成数据丢失: 假设现在有两个线程T1和T2,两个线程都走到put函数,且假设两个线程中key%NBUCKET相等,即要插入同一个散列桶中。...我们已经您提供了barrier_init()。您工作是实现barrier(),这样panic就不会发生。我们您定义了struct barrier;它字段供您使用。

26620

HashMap知识点整理

int TREEIFY_THRESHOLD = 8; //恢复链式结构临界值 6 static final int UNTREEIFY_THRESHOLD = 6; //哈希表 transient...*load factor 计算出来,当 size 到达这个值时, 就会进行扩容操作 int threshold; //负载因子 final float loadFactor; //当哈希表大小超过这个阈值...关于put方法如果超过最大容量是1<<30,按常理并不会放入超过此数值,但如果极限值超过这个值,就将threshold修改为Integer.MAX_VALUE(此时大小已经是231次方了,表名已经不进行扩容了...明显如果到1,现插入节点链表会极限大,但其他位置可能为空,造成空间复杂度o(n) 那么如果小于0.75,就会频繁扩容,造成空间浪费,所以计算后到达元素个数0.75进行扩容 final V putVal...1.8以后,数组+链表+红黑树 当碰撞个数大于8时,并且总容量大于64时,将链表转为红黑树,除了添加以外其他效率都高,jdk1.8加到链表末尾,扩容以后不需要运行hash算法计算hashcode值。

33820

JAVA-FileInputStream之read方法「建议收藏」

1.因为ANSI编码没有文件头,因此数字字符1只占一个字节,并且1Ascii码49因此输出49,而Unicode格式有2个字节文件头,并且以2个字节表示一个字符,对于Ascii字符对应字符则是第...BIG ENDIAN类型:FE FF   2.从返回结果来看,返回是当前字节数据,API文档中原文:”下一个数据字节,如果已到达文件末尾,则返回 -1。”...解读: 1、最多b.length个字节数据读入一个byte数据组中,即,最多将byte数组b填满; 2、返回读入缓冲字节总数,如果因为已经到达文件末尾而没有更多数据,则返回-1。...这里即这朋友问题点,为什么用-1来判断文件结束。他理由,假设3个字节源数据,用2个字节数组来缓存,当第2次读取时候到达了文件结尾,此时应该返回-1了,岂不是只读取到了2个字节?...,因此为3个字节,这里测试读3次,从代码中可以看出,b一个byte数组,大小2,即每次可以存放2个字节。

58210

PHP编程语言垃圾回收是什么?

php $a = "new string"; 在这种情况下,新符号名称 a 会在当前作用域中创建,并且会创建新变量容器,其类型 string,值 new string。...这在长时间运行脚本中尤为棘手,比如守护进程,其中请求基本上永远不会结束,或者在大量单元测试集中。后者在运行 eZ Components 库模板组件单元测试时出现了问题。...恢复是有条件,当变量引用计数大于0时才对其做模拟恢复。同样每个变量只能恢复一次,恢复后标记为黑,基本就是步骤 B 逆运算。...根缓冲区大小是固定,可以容纳 10,000 个可能根(尽管可以通过更改 PHP 源代码中 Zend/zend_gc.c 中 GC_THRESHOLD_DEFAULT 常量并重新编译 PHP 来修改这个值...算法永远不会分析那些没有记录可能根。如果他们是循环引用一部分,将永不会清除从而导致内存泄漏产生。

17710

update语句到 redo log深入理解

前面我们分析过一个查询语句执行流程,并且解释了执行过程中涉及模块。一条查询语句一般是经过连接器、分析器、优化器、执行器等功能模块,最后到达存储引擎。...类似的,InnoDB redo log 是固定大小,比如可以配置一组 4 个文件,每个文件大小是 1GB,那么这块“粉板”总共就可以记录 4GB 操作。...从头开始写,写到末尾就又回到开头循环写,如下面这个图所示。 ? write pos 是当前记录位置,一边写一边后移,写到第 3 号文件末尾后就回到 0 号文件开头。...redo log 是循环,空间固定会用完;binlog 是可以追加写入。“追加写”是指 binlog 文件写到一定大小后会切换到下一个,并不会覆盖以前日志。...两阶段提交 为什么必须有“两阶段提交”呢?这是为了让两份日志之间逻辑一致。要说明这个问题,我们得从文章开头那个问题说起:怎样让数据库恢复到半个月内任意一秒状态?

61320

数据日志系统解决了好多大问题!

InnoDBredo log是有固定大小,比如可以配置 一组4个文件(logfile-1,logfile-2,logfile-3,logfile-4),每个文件大小是1GB,那么它总共可以记录4GB...一个环状循环结构,从头开始写,写到末尾又回到开始循环写。 redo中环状结构 结构图: ? write pos是当前记录位置,一边写一边后移,环状结构,写到3号文件末尾就会回到0号文件开头。...checkpoint是当前擦除位置,也是往后推移并且循环。...“追加写”是只belog文件写到一定大小后会切换到下一个,并不会覆盖以前日志。...redo日志是环状结构循环写入,并且到了配置固定大小后会被擦除,误删除数据库或表数据时候,备份可能会出现无法全部还原。

95410

javascript入门到进阶 - js系列一:三种基本数据结构

对应获取栈底方法 pop(就是弹出数组末尾元素) arr.pop() 对应添加末尾元素方法 push (向数组末尾添加元素) arr.push("hahah") 总的来说 1 栈是一种数据结构...四 总结 调用栈其实就是一种解析器去处理程序机制,它是栈数据结构。它能追踪子程序运行状态。(1)当脚本要调用一个函数时,解析器把该函数添加到栈中并且执行这个函数。...并形成一个栈帧 (2)任何被这个函数调用函数会进一步添加到调用栈中,形成另一个栈帧,并且运行到它们被上个程序调用位置。(3)当执行完这个函数后,如果它没有调用其他函数,则它会从调用栈中推出。...如上图所示,队列大小size = 11,队列head指向 5 ,队尾fail指向10,当向队尾添加一个元素F,这时fail = 0,这时再向队尾添加一个元素G,这时fail = 1.队列就变为下图所示...循环队列很显然避免了数组搬移操作。 循环队列难点在于如何确定队空和队满判定条件以及head和fail变化. 总结一下规律,fail变化,当fail=10,如何让fail = 0呢?

64820

MySQL基础篇2 mysql日志系统

log 是固定大小,比如可以配置一组 4 个文件,每个文件大小是 1GB,那么这块“粉板”总共就可以记录 4GB 操作。...从头开始写,写到末尾就又回到开头循环写,如下面这个图所示 image.png write pos 是当前记录位置,一边写一边后移,写到第 3 号文件末尾后就回到 0 号文件开头 checkpoint...是当前要擦除位置,也是往后推移并且循环,擦除记录前要把记录更新到数据文件 write pos 和 checkpoint 之间是“粉板”上还空着部分,可以用来记录新操作 如果 write pos...“追加写”是指 binlog 文件写到一定大小后会切换到下一个,并不会覆盖以前日志。 我们再来看一下执行update流程 执行器先找引擎取 ID=2 这一行。...然后你会发现,如果需要用这个 binlog 来恢复临时库的话,由于这个语句 binlog 丢失,这个临时库就会少了这一次更新,恢复出来这一行 c 值就是 0,与原库值不同。

43340

java基础之控制流程迭代语句

二、格式 1、while循环   while 循环格式如下: while(布尔表达式){ 语句 }   下面这个简单例子可产生随机数。 (1)用到了 random()方法。...而在 while 循环结构中,若条件第一次就为false,那么其中语句根本不会执行,区别主要如下图。 名称用法while先判断条件,再执行,执行0次或者多次。...每次循环前,需要执行下面步骤顺序, (1)测试一下布尔表达式。 (2)若获得结果是 false,就会继续执行紧跟在 for 语句里面的代码。 (3)在每次循环末尾,会计算一次步进。   ...1、for循环中break,continue用法   下面这个程序向大家展示了break 和continue 在 for循环例子。 (1)在这个 for 循环中,i 永远不会到达 100。...0 9 18 27 36 45 54 63 72 2、while循环中break,continue 用法    下面这个程序向大家展示了break 和continue 在while 循环例子。

70410

层层递进——宽度优先搜索(BFS)

此时你会发现(2,2)这个点既可以从(1,2)到达,也可以从(2,1)到达并且都只使用了两步。 注:为了防止一个点多次被走到,这里需要一个数组来记录一个点是否已经被走到过。 ?...50*50,因此队列扩展不会超过2500个 int head,tail; int a[51][51] = {0}; //用来存储地图 int book[51][51] = {0}; //数组book...[2501]; //因为地图大小不超过50*50,因此队列扩展不会超过2500个 int a[51][51] = {0}; //用来存储地图 int book[51][51...] = {0}; //数组book作用是记录哪些点已经在队列中了,防止一个点被重复扩展,并全部初始化为0 //定义一个用于表示走方向数组 int next[4][2] = {...第一行有两个数n m,n表示迷宫行数,m表示迷宫列数。 接下来n行m列为迷宫,0表示空地,1表示障碍物。 最后一行四个数,前两个数表示迷宫入口x和y坐标,后两个小哈x和y坐标。

67540

ArrayList源码解析

查阅资料后,大概知道:transient标识之后是不被序列化 但是ArrayList实际容器就是这个数组为什么标记为不序列化??那岂不是反序列化时会丢失原来数据?...,为什么注释却说初始容量10。...如果null,则循环遍历数组,移除第一个null元素 如果非null,则循环遍历数组,移除第一个与指定元素相同(equals() 返回true)元素 可以看到最后都是移除指定位置元素,源码中为了追求最佳性能...(elementData)中未包含在c中元素,全部放在elementData数组最前面,假设为w个,最后再统一置空后面的元素,并且记录当前数组有效元素个数w.即完成了删除工作. 4....添加:如果是添加到数组指定位置,那么可能会挪动大量数组元素,并且可能会触发扩容机制;如果是添加到末尾的话,那么只可能触发扩容机制.

48920

前端学习数据结构与算法系列(五):冒泡排序理解与实现

特点 从序列末尾开始比较相邻两个数字大小 如果比较数据比左边相邻数据小,则左移当前比较数据。 直至当前比较数据位置等于当前比较次数时,则一轮结束。...比较完一轮后,如果当前轮数不等于序列长度,则继续从末尾开始比较。 图解示例 如图所示,将下列数字按从小到大顺序进行排列。 从数据末尾开始比较相邻两个数字大小 比较后,发现6<7,故交换位置。...当比较到数据左边第2个位置时,序列中第2小数字也就到达了指定位置。 重复上述操作,直到当前比较数字位置当前比较次数,即排序完成。...实现思路 声明一个函数,参数一个数组 初始化比较轮数1 对数组进行遍历 在循环中获取当前比较值在数组下标:数组长度 - 当前循环次数 在循环中获取当前比较值左侧相邻值在数组下标:数组长度...- (当前循环次数+2) 得到下标后,分别获取当前比较值和与之左侧相邻值 判断当前比较值数组下标是否等于当前轮数 如果相等则轮数自增1,如果当前轮数不等于数组长度则让循环继续执行 如果不相等,则比较当前值与左侧相邻值大小

69720

「基础编程学习」 「PHP7数组详解」:第1章 (6)循环结构

# 1.11 循环结构 循环这个太常用了。我们为什么使用计算机,而不是手动一个一个处理,就是因为计算机善于处理循环结构。把最枯燥部分,扔给机器,它喜欢这样。 循环应用场景,很多。...foreach 仅能够应用于数组和对象,如果尝试应用于其他数据类型变量,或者未初始化变量将发出错误信息。 你如果曾留意一些框架,或者代码库,对此君一定不会陌生。没错儿,到处都是它。...上面这段代码,是对文件操作句柄$fp,判断其是否到了文件结尾feof()函数。 如果不是文件末尾,继续循环。执行结构体内语句。...有时候为了写一个命令行运行文件,要守护进程,永远不过期,永远不退出,那可能就需要一个死循环,用云运行下去。下面的代码看一下: ? 大家看,这就是一个while(true)典型循环为什么这么用?...知道将字符串字段到最后没有任何值,那么strlen($nvpstr) === 0,这时候while循环退出,函数返回。 大家完全可以发挥想象力,使用这简单结构,构造出复杂应用。

70820

一文搞定HashMap实现原理和面试

我们也可以设置大于1负载因子,这样数组不会扩充,牺牲性能,节省内存。 为了解决碰撞,数组元素是单向链表类型。当链表长度到达一个阈值时(7或8),会将链表转换成红黑树提高性能。...对于第三点补充说明,检查链表长度转换成红黑树之前,还会先检测当前数组数组是否到达一个阈值(64),如果没有到达这个容量,会放弃转换,先去扩充数组。...== null,到达链表末尾,添加新节点,如果长度足够,转换成树结构。...答:当然可以,只要它遵守了equals和hashCode方法定义规则,并且当对象插入到Map中之后将不会再改变。)...如果条件竞争发生了,那么就死循环了。这个时候,你可以质问面试官,为什么这么奇怪,要在多线程环境下使用HashMap呢?:) 10、HashMap是非线程安全,那么原因是什么呢?

72610
领券