基于BIO实现简易版本的消息队列(MQ)

设计一个简单的消息队列

引言: 学习消息队列的基本原理,可以更好的发挥消息队列在项目中起到的作用

消息处理中心

保存消息

package com.hf.core;

import java.util.concurrent.ArrayBlockingQueue;

/**
 * @author : [HF_D]
 * @version : [v1.0]
 * @description : [消息处理中心]
 * @createTime : [2021/6/22 18:25]
 */
public class Broker {
    /**
     * 队列存储消息的最大数量
     */
    private final static int MAX_VALUE = 10;
    /**
     * 保存消息数据的容器
     */
    private static ArrayBlockingQueue<String> messageQueue = new ArrayBlockingQueue<String>(MAX_VALUE);

    /**
     * 生产消息
     *
     * @param msg 消息
     */
    public static void produce(String msg) {
        //存入消息
        if (messageQueue.offer(msg)) {
            System.out.println("成功向消息处理中心投递消息: " + msg + ",当前暂存的消息数量是:" + messageQueue.size());
        } else {
            System.out.println("消息处理中心内暂存的消息达到最大负荷,不能继续放入消息");
        }
    }

    /**
     * 消费消息
     *
     * @return
     */
    public static String consume() {
        //取出一条消息
        String msg = messageQueue.poll();
        if (msg != null) {
            System.out.println("已经消费消息:" + msg + ",当前暂存的消息数量是:" + messageQueue.size());
        } else {
            System.out.println("消息处理中心内没有消息可供消费!");
        }
        return msg;
    }
}

消息队列服务器

提供客户端访问消息队列的入口

package com.hf.server;

import com.hf.core.Broker;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * @author : [HF_D]
 * @version : [v1.0]
 * @description : [消息队列服务器]
 * @createTime : [2021/6/22 18:38]
 */
public class BrokerServer implements Runnable {
    /**
     * 服务器端口
     */
    public static int SERVICE_PORT = 9999;
    /**
     * Socket
     */
    private final Socket socket;

    public BrokerServer(Socket socket) {
        this.socket = socket;
    }

    @Override
    public void run() {
        try (
                BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                PrintWriter printWriter = new PrintWriter(socket.getOutputStream());
        ) {
            while (true) {
                String str = br.readLine();
                if (str == null) {
                    continue;
                }
                System.out.println("接收到原始消息:" + str);
                if (str.equals("CONSUME")) {
                    //取出消息
                    String message = Broker.consume();
                    printWriter.println(message);
                    printWriter.flush();
                } else {
                    //存入消息
                    Broker.produce(str);
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) throws IOException {
        //开启服务端的端口,
        ServerSocket server = new ServerSocket(SERVICE_PORT);
        while (true) {
            //等待客户端连接,每一个连接开启一个线程
            BrokerServer brokerServer = new BrokerServer(server.accept());
            new Thread(brokerServer).start();
        }
    }
}

客户端API

提供客户端访问消息队列服务器的API

package com.hf.client;

import com.hf.server.BrokerServer;

import java.io.*;
import java.net.InetAddress;
import java.net.Socket;

/**
 * @author : [HF_D]
 * @version : [v1.0]
 * @description : [提供客户端访问消息队列服务器的API]
 * @createTime : [2021/6/22 18:50]
 */
public class MqClient {
    /**
     * 生产消息
     *
     * @param message 消息
     * @throws IOException
     */
    public static void produce(String message) throws IOException {
        Socket socket = new Socket(InetAddress.getLocalHost(), BrokerServer.SERVICE_PORT);
        try (
                PrintWriter printWriter = new PrintWriter(socket.getOutputStream());
        ) {
            printWriter.println(message);
            printWriter.flush();
        }
    }

    /**
     * 消费消息
     *
     * @return 消息
     * @throws IOException
     */
    public static String consume() throws IOException {
        Socket socket = new Socket(InetAddress.getLocalHost(), BrokerServer.SERVICE_PORT);
        try (
                BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                PrintWriter printWriter = new PrintWriter(socket.getOutputStream());
        ) {
            //告诉服务器 消费消息
            printWriter.println("CONSUME");
            printWriter.flush();
            //获取到取出的消息
            String message = bufferedReader.readLine();
            return message;
        }
    }
}

测试

消费者测试

ConsumeClient

package com.hf.test;

import com.hf.client.MqClient;

import java.io.IOException;

/**
 * @author : [HF_D]
 * @version : [v1.0]
 * @description : [测试消费者]
 * @createTime : [2021/6/22 19:03]
 */
public class ConsumeClient {
    public static void main(String[] args) throws IOException {
        MqClient client = new MqClient();
        String consume = client.consume();
        System.out.println("获取的消息为:" + consume);
    }
}

生产者测试

ProduceClient

package com.hf.test;

import com.hf.client.MqClient;

import java.io.IOException;

/**
 * @author : [HF_D]
 * @version : [v1.0]
 * @description : [测试生产者]
 * @createTime : [2021/6/22 19:02]
 */
public class ProduceClient {
    public static void main(String[] args) throws IOException {
        MqClient client = new MqClient();
        client.produce("Hello World");
    }
}

项目结构

在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值