You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java基于Semaphore实现呼叫中心出现呼叫丢失问题求解

问题核心错误

你的现有实现存在两个核心逻辑问题:

  1. 仅使用单个信号量,完全没有限制消费者的取操作时机:队列无数据时消费者仍会执行poll()返回null,相当于空占了应答名额,后续入队的呼叫自然没有对应的消费者处理,就出现了呼叫丢失的情况。
  2. 使用的LinkedList是非线程安全队列,多线程并发调用add()和poll()时会出现队列结构损坏,导致部分呼叫没有正确入队或出队。

修正后实现(完全符合约束要求)

仅修改服务类即可,所有逻辑均基于Semaphore实现,仅调用acquire()和release()方法,未使用其他锁结构:

import java.util.Queue;
import java.util.concurrent.Semaphore;
import java.util.LinkedList;

public final class BoundedCallCenterSemaphore implements BoundedCallCenter {
    private final Queue<Call> pendingCalls = new LinkedList<Call>();
    // 空缓冲区信号量:初始值为队列最大容量,控制生产者最多放入的呼叫数
    private final Semaphore empty = new Semaphore(MAX_NUMBER_OF_PENDING_CALLS, true);
    // 满缓冲区信号量:初始值为0,控制消费者仅在队列有呼叫时才能取
    private final Semaphore full = new Semaphore(0, true);
    // 互斥信号量:初始值为1,保证队列操作的原子性
    private final Semaphore mutex = new Semaphore(1, true);

    public void receive(Call call) throws Exception {
        // 先获取空缓冲区许可,队列满时阻塞
        empty.acquire();
        // 获取队列操作权限
        mutex.acquire();
        try {
            pendingCalls.add(call);
        } finally {
            // 释放队列操作权限
            mutex.release();
        }
        // 通知消费者有新的呼叫可处理
        full.release();
    }

    public Call answer() throws InterruptedException {
        // 先获取满缓冲区许可,队列空时阻塞,不会执行后续poll逻辑
        full.acquire();
        // 获取队列操作权限
        mutex.acquire();
        Call call;
        try {
            call = pendingCalls.poll();
        } finally {
            // 释放队列操作权限
            mutex.release();
        }
        // 通知生产者有空位可以放入新呼叫
        empty.release();
        return call;
    }
}

实现说明

  1. 两个计数信号量分别控制生产者和消费者的执行时机:生产者必须等有空位才能放呼叫,消费者必须等有呼叫才能取,完全避免了消费者取到null的情况,也不会出现队列溢出。
  2. 互斥信号量保证同一时间只有一个线程操作队列,完全解决了非线程安全队列的竞态问题,不会出现呼叫丢失或重复应答的情况。
  3. 所有阻塞都是通过Semaphore的acquire()实现,没有忙等,完全符合作业要求。

内容的提问来源于stack exchange,提问作者Requieem

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 01:45:00