队列长度固定,队列有头部指针(front)、尾部指针(rear)两个指针
每插入一个元素,尾部指针前移一位
每取出一个元素,头部指针前移一位
队列满了之后,取出一个元素,再加入一个元素,尾部指针归零
取元素的个数达到队列最大长度之后,头部指针归零

1、下面上代码实操,先来个接口类
package com
.fss
.util
.queue
;
public
interface
Queue
<
T
>
{
/**
* 添加元素
*/
boolean
push
(
T t
)
;
/**
* 取出元素,先进先出
*/
T
pop
(
)
;
/**
* 判断队列是否已满
*/
boolean
isFull
(
)
;
/**
* 判断队列是否为空
*/
boolean
isEmpty
(
)
;
}
2、再来一个抽象类吧,保证子类自己来实现接口
package com
.fss
.util
.queue
;
public abstract
class
AbstractQueue
<
T
>
implements
Queue
<
T
>
{
@Override
public boolean
push
(
T t
)
{
throw
new
UnsupportedOperationException
(
"不支持的方法"
)
;
}
@Override
public
T
pop
(
)
{
throw
new
UnsupportedOperationException
(
"不支持的方法"
)
;
}
@Override
public boolean
isFull
(
)
{
throw
new
UnsupportedOperationException
(
"不支持的方法"
)
;
}
@Override
public boolean
isEmpty
(
)
{
throw
new
UnsupportedOperationException
(
"不支持的方法"
)
;
}
}
3、队列实现类
package com
.fss
.util
.queue
;
import java
.util
.Arrays
;
public
class
CycleQueue
<
T
>
extends
AbstractQueue
<
T
>
implements
Queue
<
T
>
{
// 队列初始化大小
private
static final int
CAPCAITY
=
6
;
// 队列头
volatile int front
;
// 队列尾
volatile int rear
;
// 队列元素
volatile
T
[
] arrays
;
public
CycleQueue
(
)
{
this
.arrays
=
(
T
[
]
)
new
Object
[
CAPCAITY
]
;
}
/**
* 添加元素,队尾下标+1
*/
@Override
public boolean
push
(
T t
)
{
synchronized
(
this
)
{
if
(
!
isFull
(
)
)
{
arrays
[rear
]
= t
;
// 队尾指针+1后的值等于队列容积时,队尾下标重置为0,以实现队列循环使用
if
(
++rear
==
CAPCAITY
)
{
rear
=
0
;
}
return
true
;
}
return
false
;
}
}
/**
* 取出元素,队列头下标+1
*/
@Override
public
T
pop
(
)
{
synchronized
(
this
)
{
if
(
!
isEmpty
(
)
)
{
System
.out
.
print
(
"当前数组: "
)
;
for
(int i
=
0
; i
<arrays
.length
; i
++
)
{
System
.out
.
print
(arrays
[i
]
+
","
)
;
}
System
.out
.
print
(
" - "
)
;
final
T cur
= arrays
[front
]
;
arrays
[front
]
=
null
;
front
++
;
// 队头指针+1后的值等于队列容积时,队头下标重置为0,以实现队列循环使用
if
(front
==
CAPCAITY
)
{
front
=
0
;
}
return cur
;
}
return
null
;
}
}
/**
* 判断队列是否满
*/
@Override
public boolean
isFull
(
)
{
synchronized
(
this
)
{
return front
== rear
&& arrays
[rear
]
!=
null
;
}
}
/**
* 判断队列是否为空
*/
@Override
public boolean
isEmpty
(
)
{
synchronized
(
this
)
{
return front
== rear
&& arrays
[rear
]
==
null
;
}
}
}
4、大功告成,现在起3个线程类,2个生产者,1一个消费者,生产速度大于消费速度
生产者(当队列满了之后等待,有元素被取出则继续生产)
package com
.fss
.util
.thread
;
import com
.fss
.util
.queue
.CycleQueue
;
import java
.util
.Random
;
public
class
PushQueueThread
extends
Thread
{
private CycleQueue queue
;
private String threadName
;
public
PushQueueThread
(
CycleQueue queue
, String threadName
)
{
this
.queue
= queue
;
this
.threadName
= threadName
;
}
//java学习交流:737251827 进入可领取学习资源及对十年开发经验大佬提问,免费解答!
@Override
public
void
run
(
)
{
synchronized
(
queue
)
{
while
(
true
)
{
int i
=
new
Random
(
)
.
nextInt
(
1000
)
;
while
(queue
.
isFull
(
)
)
{
try
{
System
.out
.
print
(threadName
+
" - 发现队列满了,排队等位中。。。。\n"
)
;
queue
.
wait
(
)
;
}
catch
(InterruptedException e
)
{
e
.
printStackTrace
(
)
;
}
}
queue
.
push
(i
)
;
System
.out
.
print
(threadName
+
"-放入元素: "
+ i
+
"\n"
)
;
try
{
queue
.
wait
(
100
)
;
}
catch
(InterruptedException e
)
{
e
.
printStackTrace
(
)
;
}
}
}
}
}
消费者(取出元素之后通知生产者生产)
package com
.fss
.util
.thread
;
import com
.fss
.util
.queue
.CycleQueue
;
import java
.util
.List
;
public
class
PopQueueThread
extends
Thread
{
private CycleQueue queue
;
private String threadName
;
public
PopQueueThread
(
CycleQueue queue
, String threadName
)
{
this
.queue
= queue
;
this
.threadName
= threadName
;
}
@Override
public
void
run
(
)
{
synchronized
(
queue
)
{
while
(
true
)
{
if
(
!queue
.
isEmpty
(
)
)
{
Object o
= queue
.
pop
(
)
;
System
.out
.
print
(threadName
+
"-取出元素: "
+o
+
"\n"
)
;
try
{
queue
.
wait
(
100
)
;
System
.out
.
println
(threadName
+
" - 有空位了,下一位上来吧。。。"
)
;
queue
.
notifyAll
(
)
;
}
catch
(InterruptedException e
)
{
e
.
printStackTrace
(
)
;
}
}
else
{
try
{
System
.out
.
print
(threadName
+
" - 发现队列空了,坐等客人上门。。。。\n"
)
;
queue
.
wait
(
200
)
;
queue
.
notifyAll
(
)
;
}
catch
(InterruptedException e
)
{
e
.
printStackTrace
(
)
;
}
}
}
}
}
}
5、起一个main方法测试吧
package test
;
import com
.fss
.util
.queue
.CycleQueue
;
import com
.fss
.util
.thread
.PopQueueThread
;
import com
.fss
.util
.thread
.PushQueueThread
;
public
class
CycleQueueTest
{
public
static
void
main
(
String
[
] args
)
{
CycleQueue queue
=
new
CycleQueue
(
)
;
PushQueueThread pushThread1
=
new
PushQueueThread
(queue
,
"Push1"
)
;
PushQueueThread pushThread2
=
new
PushQueueThread
(queue
,
"Push2"
)
;
PopQueueThread popThread
=
new
PopQueueThread
(queue
,
"Pop1"
)
;
pushThread1
.
start
(
)
;
pushThread2
.
start
(
)
;
popThread
.
start
(
)
;
}
}
Push1
-放入元素:
148
Push2
-放入元素:
694
当前数组:
148
,
694
,
null
,
null
,
null
,
null
,
- Pop1
-取出元素
:
148
Push1
-放入元素:
797
Push2
-放入元素:
781
Pop1
- 有空位了,下一位上来吧。。。
当前数组:
null
,
694
,
797
,
781
,
null
,
null
,
- Pop1
-取出元素
:
694
Push2
-放入元素:
639
Push1
-放入元素:
390
Push2
-放入元素:
633
Pop1
- 有空位了,下一位上来吧。。。
当前数组:
633
,
null
,
797
,
781
,
639
,
390
,
- Pop1
-取出元素
:
797
Push1
-放入元素:
843
Push2
-放入元素:
945
Pop1
- 有空位了,下一位上来吧。。。
当前数组:
633
,
843
,
945
,
781
,
639
,
390
,
- Pop1
-取出元素
:
781
Push2
-放入元素:
33
Push1
- 发现队列满了,排队等位中。。。。
Pop1
- 有空位了,下一位上来吧。。。
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/70010294/viewspace-2847204/ ,如需转载,请注明出处,否则将追究法律责任。