队列配置:
@Component
@Slf4j
public class QueueConfig {
//队列最大容量
private static final int MAX_CAPACITY = 3;
//队列
public final ConcurrentLinkedQueue<String> queue = new ConcurrentLinkedQueue<>();
public synchronized ConcurrentLinkedQueue<String> add (String userName){
while (queue.size() >= MAX_CAPACITY){
try {
log.info("当前排队人数已满,请等待!");
wait();
}catch (Exception ignored){}
}
queue.add(userName);
log.info("排队人数+1,目前排队数量:{}",queue.size());
notifyAll();
return queue;
}
public synchronized String getNext(){
while (queue.isEmpty()){
try {
wait();
} catch (InterruptedException ignored) {
}
}
String remove = queue.remove();
log.info("========{}:执行完毕,排队人数-1,目前排队数量:{}",remove,queue.size());
notifyAll();
return remove;
}
}
}
使用:
@Service
@Slf4j
@RequiredArgsConstructor
public class QueueServiceImpl implements QueueService {
public final QueueConfig queueConfig;
@Override
public void test(String name) {
new Thread(new Runnable() {
@Override
public void run() {
queueConfig.add(name);
exec();
}
}).start();
}
private final Lock lock = new ReentrantLock();
private void exec() {
if (queueConfig.queue.peek() != null){
lock.lock();
try {
log.info("========={}:正在执行操作=========",queueConfig.queue.peek());
try {
Thread.sleep(15000);
} catch (InterruptedException e) {
}
//执行完毕移除当前
queueConfig.getNext();
}finally {
lock.unlock();
}
}
}
}
测试:
使用了4个请求来模拟操作,最大·队列是3:
2024-12-08 10:46:10.944 INFO 67308 --- [ Thread-2] com.study.question.config.QueueConfig : 排队人数+1,目前排队数量:1
2024-12-08 10:46:10.945 INFO 67308 --- [ Thread-2] c.s.q.service.impl.QueueServiceImpl : =========1:正在执行操作=========
2024-12-08 10:46:13.261 INFO 67308 --- [ Thread-3] com.study.question.config.QueueConfig : 排队人数+1,目前排队数量:2
2024-12-08 10:46:15.587 INFO 67308 --- [ Thread-4] com.study.question.config.QueueConfig : 排队人数+1,目前排队数量:3
2024-12-08 10:46:17.721 INFO 67308 --- [ Thread-5] com.study.question.config.QueueConfig : 当前排队人数已满,请等待!
2024-12-08 10:46:25.949 INFO 67308 --- [ Thread-2] com.study.question.config.QueueConfig : ========1:执行完毕,排队人数-1,目前排队数量:2
2024-12-08 10:46:25.949 INFO 67308 --- [ Thread-5] com.study.question.config.QueueConfig : 排队人数+1,目前排队数量:3
2024-12-08 10:46:25.949 INFO 67308 --- [ Thread-3] c.s.q.service.impl.QueueServiceImpl : =========2:正在执行操作=========
2024-12-08 10:46:40.960 INFO 67308 --- [ Thread-3] com.study.question.config.QueueConfig : ========2:执行完毕,排队人数-1,目前排队数量:2
2024-12-08 10:46:40.960 INFO 67308 --- [ Thread-4] c.s.q.service.impl.QueueServiceImpl : =========3:正在执行操作=========
2024-12-08 10:46:55.964 INFO 67308 --- [ Thread-4] com.study.question.config.QueueConfig : ========3:执行完毕,排队人数-1,目前排队数量:1
2024-12-08 10:46:55.964 INFO 67308 --- [ Thread-5] c.s.q.service.impl.QueueServiceImpl : =========4:正在执行操作=========
2024-12-08 10:47:10.971 INFO 67308 --- [ Thread-5] com.study.question.config.QueueConfig : ========4:执行完毕,排队人数-1,目前排队数量:0
分析结果:
可以看到当第一个请求1过来时候会加到队列,然后直接执行操作,
后续有进来两个请求排队
当第4个请求进来时候·,队列已经满了,需要等待队列空位置
1执行完后,可以看到第4个请求入队,现在有3个在队列中
接着2执行,3执行....直到队列是空。