一个简单的生产者和消费者客服实现

简介: 一个简单的生产者和消费者客服实现

1.职能分类



生产者-客服登录到系统
消费者-客户消费客服
复制代码


2.简单的流程



1.没有有效的客服的时候就等待客服连接进入
2.客服登录系统,可用客服+1
3.客户消费客服,可用客服-1 
    这里是随机查询一个可用的客服
    也可以写一些其他的策略比如获取可用的第一个
                         比如客服维护个服务统计按照最小服务量的
4.当沟通完成后,可用客服+1
5.客服退出以后,可用客服-1
复制代码


3.实现



可用客服这里用信号量Semaphore来做判断
客户消费客服采用线程方式
客服的操作采用CopyOnWriteArrayList
复制代码


3.1客服的简单实体定义


public class Customer {
  private String name;//名称
  private String code;//代号 唯一
}
复制代码


3.2客服的管理实现


public class CustomerManagerList {
  //信号量统计可以使用的客服信息
  public static Semaphore workSemaphore=new Semaphore(0); 
  //客服接入列表用了线程安全的CopyOnWriteArrayList
  private static List<Customer> cusSet= new CopyOnWriteArrayList<Customer>();
        //工作的用了线程安全的CopyOnWriteArrayList
  private static List<Customer> cusWorkSet= new CopyOnWriteArrayList<Customer>();
  //客户添加进入
  public static void addCustomer(Customer c) {
    cusSet.add(c);
    System.out.println(c.toString()+"接入。。。");
    workSemaphore.release();
  }
  //工作中的客服
  public static void addWork(Customer c) throws InterruptedException {
    cusWorkSet.add(c);
  }
  //工作结束
  public static void removeWork(Customer c) {
    cusWorkSet.remove(c);
    workSemaphore.release();
  }
  //退出
  public static void removeCustomer(Customer c) throws InterruptedException {
    cusSet.remove(c);
    cusWorkSet.remove(c);
      workSemaphore.tryAcquire();
  }
  //随机获取下一个可用的客服信息
  public static Customer getWorkRandom() throws InterruptedException {
    workSemaphore.acquire();
    List<Customer> cusNotWork=new CopyOnWriteArrayList<Customer>();
    cusNotWork.addAll(cusSet);
    cusNotWork.removeAll(cusWorkSet);
    if(0==cusNotWork.size()) {
      workSemaphore.release();//没有数据消耗的补上来
      return null;
    }else {
      Customer result=cusNotWork.get(new Random().nextInt(cusNotWork.size()));
      addWork(result);//添加到工作
      return result;
    }
  }
}
复制代码


3.3客服的消费实现


//通过线程的方式去消费客服
public class CustomerRun implements Runnable{
  @Override
  public void run() {
    try {
          System.out.println("等待中...");
          System.out.println(CustomerManager.workSemaphore.availablePermits());
          Customer c = CustomerManagerList.getWorkRandom();
      if (null == c) {
        return;
      }
      System.out.println(c.toString() + "沟通中...");
      Thread.sleep(5 * 1000);
      System.out.println(c.toString() + "沟通结束...");
      CustomerManagerList.removeWork(c);
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
  }
}
复制代码


3.4 测试


public static void test2() {
         //客户消费客服
  for (int i = 0; i < 100; i++) {
    CustomerRun cr = new CustomerRun();
    Thread t = new Thread(cr);
    t.start();
  }
        //模拟添加客服
  for (int i = 0; i < 15; i++) {
    CustomerManagerList.addCustomer(new Customer("name" + i, "code" + i));
  }
        //模拟添加客服
  for (int i = 15; i < 20; i++) {
    CustomerManagerList.addCustomer(new Customer("name" + i, "code" + i));
  }
}
复制代码


3.5效果


网络异常,图片无法展示
|

相关文章
|
3月前
|
Java
并发编程之生产者和消费者问题
该博客文章通过Java代码示例介绍了生产者和消费者问题的线程间通信解决方案,演示了如何使用synchronized关键字和wait/notifyAll方法来实现线程间的同步和资源的协调访问。
|
3月前
|
安全
LinkedBlockingQueue实现的生产者和消费者模型
LinkedBlockingQueue实现的生产者和消费者模型
34 1
|
3月前
|
设计模式 安全 Python
生产者与消费者模式
生产者与消费者模式
|
5月前
|
消息中间件 网络协议 物联网
消息队列 MQ产品使用合集之如何让消费者不从最开始进行消费,而是从最后一条消息开始消费
消息队列(MQ)是一种用于异步通信和解耦的应用程序间消息传递的服务,广泛应用于分布式系统中。针对不同的MQ产品,如阿里云的RocketMQ、RabbitMQ等,它们在实现上述场景时可能会有不同的特性和优势,比如RocketMQ强调高吞吐量、低延迟和高可用性,适合大规模分布式系统;而RabbitMQ则以其灵活的路由规则和丰富的协议支持受到青睐。下面是一些常见的消息队列MQ产品的使用场景合集,这些场景涵盖了多种行业和业务需求。
|
6月前
|
负载均衡 Java API
SpringCloud深入理解 | 生产者、消费者
SpringCloud深入理解 | 生产者、消费者
129 0
|
消息中间件
ActiveMQ消费者消费消息(点对点模式)
上篇博客写了生产者生产消息:ActiveMQ向消息队列存入消息
|
安全 数据处理
线程中的生产者和消费者模式
线程中的生产者和消费者模式
127 0
线程中的生产者和消费者模式
|
设计模式 安全
生产者与消费者模型
生产者与消费者模型
99 0
生产者与消费者模型
2.6操作系统(生产者消费问题 多生产者—消费者问题 吸烟者问题)
1.生产者消费问题 能否改变相邻P、V操作的顺序? 2.多生产者—消费者问题 如何实现? 可不可以不用互斥信号量? 如果盘子(缓冲区)容量为2 知识回顾与重要考点 3.吸烟者问题 如何实现
2.6操作系统(生产者消费问题 多生产者—消费者问题 吸烟者问题)
|
消息中间件 存储 SQL
MQ系列6:消息的消费
MQ系列6:消息的消费
260 0
MQ系列6:消息的消费