队列的简单理解

本文介绍了队列的基本概念和特点,包括先进先出的运作机制,以及基于数组的普通队列实现。进一步讨论了循环队列如何避免数据搬移,并解释了阻塞队列和并发队列的概念。在并发队列中,通过循环列表和CAS原子操作保证线程安全。最后,提到了线程池中处理资源请求的两种策略:非阻塞的拒绝和排队处理。
摘要由CSDN通过智能技术生成

队列的简单理解

定义:我们可以把它想象成排队买票先来的先买,后来的人只能站在队伍的末尾,不允许插队。

队的特点:先进先出。两个基本操作:入队和出队。

入队指的是将数据放到队伍尾部,出队指的是从队列头部取出数据

基于数组实现的队列

public class ArrayQueue{
    private String[] items;
    private int n=0;  
    private int head=0;  //队头下标
    private int tail=0;	 //队尾下标
    
    public ArrayQueue(int capacity){
        items=new String[capacity];
        n=capacity;
    }
    
    public boolean enqueue(string item){
    	if (tail==n) 
    	return false;  //tail=n表示队列已满
    	items[tail]=item;
    	++tail;
   		return true;
	}
    
    public boolean dequeue{
    	if (head=tail)
    	return null;  //head=tail表示队列为空
    	String ret=items[head];
    	++head;
    	return ret;
	}
}	

对于队列我们需要两河指针 一个head指针,指向队头;一个tail指针,指向队尾。

假设下,

当a,b,c,d依次入队后,队列中的head指针指向下标为0的位置,tail指针指向下标为4的位置,

当ab出队后,队列中head指针指向下标为2的位置,tail指针指向下标为4的位置

随着不断入队和出队 head和tail指针都会持续往后移动

当tail指针移到最右边的时候,即便数组中还有未占用的空间我们也无法添加数据

实际上我们并不需要每次出队是都进行搬移数据。

只有当tail指针的数据移动到数组的最右边后,如果有新的数据要入队,我们才集中触发依次数据搬移的操作

将head指针和tail指针的数据整体搬移到数组从0开始的位置。

对此我们对enqueue方法

1	public boolean enqueue(String item){
2    	if (tail==n){
3        	if (head==0)
4        	return fasle;   //tail==n&&head=0 表示队列已满
5        	for (int i=head;i<tail;++i){  //数据搬移
6            	items[i-head]=items[i];
7        	}
8        	tail=tail-head;
9        	head=0;
10    	}
11    	items[tail]=item;  //插入数据
12    	++tail;
13    	return true;
14	}

循环队列

当我们把队列的首尾相连那么它就变成了循环队列,这样就避免了tail==n时的数据搬移操作了。

对于循环队列 判断空为 head=tail 判断满是存在一个关系 (tail+1)%n=head;

public class CircularQueue{
    private String[] items;
    private int n=0;
    private int head=0;
    private int tail=0;
    
    public CircularQueue(int capacity){
        items =new String[capacity];
        n=capacity;
    }
    
    public boolean enqueue (String item){
        if ((tail+1)%n==head)
        return false;
        items[tail]=item;
        tail=(tail+1)%n;
        return true;
    }
    
    public String dequeue(){
        if (head==tail)
        return null;
        String ret=items[head];
        head=(head+1)%n;
        return ret;
    }
}

阻塞队列

就是队列加上阻塞特性,当队列为空的时候从队头取数据会被阻塞,直到队列有数据才返回,

在队列已满时,插入数据会被阻塞,直到队列有空闲位置。

并发队列

线程安全的队列又称为并发队列,可以基于数据的循环列表利用CAS原子操作实现并发队列。


引申

当向固定大小的线程池请求一个线程的时候,线程池如果没有空闲资源,这个时候线程池该如何处理这个请求?

是拒绝还是要求排队?

对于上面情况一般有两个策略

1.非阻塞处理,当线程池没有空闲资源时,直接拒绝新的线程请求。

2.非阻塞处理,请求排队,有资源的时候取出排队的请求继续处理

我们可以进行队列存储排队请求,如果我们选择基于链表的实现方式,可以实现一个支持无限排队的无界队列

但是会导致过多的请求排队等待,请求处理时间过长

选择基于数组的实现有界队列,当排队满的时候会拒绝排队。不过,需要设置一个大小合理的队列,太大导致请求时间过长

太小导致无法充分利用系统资源

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值