1.创建使用ArrayBlockingQueue数据模型作为消息自定义中间件的消息载体,及消费生产模式
package MyQueue; import java.util.concurrent.ArrayBlockingQueue; public class Broker { //消息队列存储最大值 private final static int MAX_SIZE=3; //保存消息数据的容器 private static ArrayBlockingQueue<String> messageQueue=new ArrayBlockingQueue<>(MAX_SIZE); //生产消息 public static void produce(String msg){ if (messageQueue.offer(msg)) { System.out.println("消息发送成功,msg:"+msg+"暂存队列中的消息数量是:"+messageQueue.size()); }else{ System.out.println("消息处理数据中心数据达到最大负荷,不能继续放入消息"); } System.out.println("=========================="); } //消费消息 public static String consume(){ String msg=messageQueue.poll(); if (msg!=null) { //消费条件满足时从消息容器中取出一条消息 System.out.println("已经消费消息:"+msg+"单签暂存的消息数"+messageQueue.size()); }else{ System.out.println("消息处理中心内没有消息可供消费!"); } System.out.println("=========================="); return msg; } }
2.创建线程模拟MQ的消息接受及发送,启动后开启消息接受及发送
package MyQueue; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.ServerSocket; import java.net.Socket; public class BrokerServer implements Runnable { public static int SERVER_PORT=9999; private final Socket socket; public BrokerServer(Socket socket){ this.socket=socket; } @Override public void run(){ try { BufferedReader in=new BufferedReader(new InputStreamReader(socket.getInputStream())); PrintWriter out=new PrintWriter(socket.getOutputStream()); while(true){ String str=in.readLine(); if (str==null) { continue; } System.out.println("接受到原始数据:"+str); if (str.equals("CONSUME")) {//consume表示需要消费一条消息 String meString=Broker.consume(); out.println(meString); out.flush(); }else{ //其他情况都表示生产消息放到消息队列中 Broker.produce(str); } } } catch (IOException e) { System.out.println(e.getMessage()); } } public static void main(String[] args) throws IOException { ServerSocket server = new ServerSocket(SERVER_PORT); while (true) { BrokerServer borkerServer=new BrokerServer(server.accept()); new Thread(borkerServer).start(); } } }
3.创建生产及消费方法,模拟消息机制
package MyQueue; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.InetAddress; import java.net.Socket; import java.net.UnknownHostException; public class MqClient { //生产者 @SuppressWarnings("unused") public static void produce(String message) throws IOException { @SuppressWarnings("resource") Socket socket = new Socket(InetAddress.getLocalHost(),BrokerServer.SERVER_PORT); PrintWriter out=new PrintWriter(socket.getOutputStream()); out.println(message); out.flush(); } //消费消息ss public static String consume() throws UnknownHostException, IOException{ @SuppressWarnings("resource") Socket socket = new Socket(InetAddress.getLocalHost(),BrokerServer.SERVER_PORT); BufferedReader in=new BufferedReader(new InputStreamReader(socket.getInputStream())); PrintWriter out=new PrintWriter(socket.getOutputStream()); //先向消息列队发送字符串“CONSUME”表示消费 out.println("CONSUME"); out.flush(); //再从消息列队获取一条消息 String message=in.readLine(); return message; } }
4.创建消息接受者
package MyQueue; import java.io.IOException; import java.net.UnknownHostException; public class ConsumeClient { public static void main(String[] args) throws UnknownHostException, IOException { MqClient mq=new MqClient(); String mes=mq.consume(); System.out.println("获取的消息为:"+mes); } }
5.创建消息生产者
package MyQueue; import java.io.IOException; public class ProduceClient { public static void main(String[] args) throws IOException { MqClient client=new MqClient(); client.produce("Hello new World!"); } }
总结:使用ArrayBlockingQueue数据结构,线程服务,socket通信模拟MQ机制可以加深对对成熟中间件的理解!