参考每特教育蚂蚁课堂
1.基于多线程的方式实现MQ(极简纯享版)
MQ就是在消费者服务和生产者服务传递信息的通道,生产者向队列中投递消息,然后消费者过来取。所以我们可以这样设计,用一个队列作为中间件,然后开启两个线程,一个是生产者线程,一个是消费者线程,生产者线程向队列中插入json串,消费者线程过来取这个就是一个简单的MQ的实现。
private static LinkedBlockingDeque<JSONObject> msgs = new LinkedBlockingDeque<JSONObject>();
public static void main(String[] args) {
// 生产线程
Thread producerThread = new Thread(new Runnable() {
@Override
public void run() {
try {
while (true) {
Thread.sleep(1000);
JSONObject data = new JSONObject();
data.put("wjz", "nb");
// 存入消息
msgs.offer(data);
}
} catch (Exception e) {
}
}
}, "生产者");
producerThread.start();
// 消费者线程
Thread consumerThread = new Thread(new Runnable() {
@Override
public void run() {
try {
while (true) {
JSONObject data = msgs.poll();
if (data != null) {
System.out.println(LocalTime.now() + Thread.currentThread().getName() + "," + data);
}
}
} catch (Exception e) {
}
}
}, "消费者");
consumerThread.start();
}
我们可以看到每隔1s生产者就会向消息队列中投放消息,消费者不断接收消息并打印结果,
如图所示大概是每隔1s消费者接收到消息。
这里面我们要注意的是不能用普通队列,必须用阻塞队列,因为阻塞队列当队列有东西的时候回自动触发消费者线程从队列里取东西,当队列为空的时候会自动触发生产者线程往里面放东西。如果用普通队列的话就会一直往队列里放东西而没有取东西,所以他会阻塞在生产者线程,不会进行线程之间的切换。
2.基于网络通讯的方式实现MQ
我们可以基于Netty实现一个MQ,首先我要有一个MQ服务端用来接收连接以及推送消息。
public class MayiktNettyMQServer {
public void bind(int port) throws Exception {
/**
* Netty 抽象出两组线程池BossGroup和WorkerGroup
* BossGroup专门负责接收客户端的连接, WorkerGroup专门负责网络的读写。
*/
EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workerGroup = new NioEventLoopGroup();
ServerBootstrap bootstrap = new ServerBootstrap();
try {
bootstrap.group(bossGroup, workerGroup)
// 设定NioServerSocketChannel 为服务器端
.channel(NioServerSocketChannel.class)
//BACKLOG用于构造服务端套接字ServerSocket对象,标识当服务器请求处理线程全满时,
//用于临时存放已完成三次握手的请求的队列的最大长度。如果未设置或所设置的值小于1,Java将使用默认值50。
.option(ChannelOption.SO_BACKLOG, 100)
// 服务器端监听数据回调Handler
.childHandler(new MayiktNettyMQServer.ChildChannelHandler());
//绑定端口, 同步等待成功;
ChannelFuture future = bootstrap.bind(port).sync();
System.out.println("当前服务器端启动成功...");
//等待服务端监听端口关闭
future