1. 如果用户的请求比较费时,可以考虑将用户的请求信息放到队列中,立即返回给用户处理中等信息,这样可以给用户比较流畅的体验,后端可以利用单独的服务消费消息,做到了解耦,提高了并发能力。

  2. 本文使用jdk为我们提供的阻塞队列api,来实现一个基于内存的简单消息队列。主要涉及的接口BlockingQueue,以及它的实现类ArrayBlockingQueue(数组实现的)和LinkedBlockingQueue(链表实现的)。

  3. BlockingQueue的主要方法

    添加元素

    put() //往队列里插入元素,如果队列已经满,则会一直等待直到队列为空插入新元素,或者线程被中断抛出异常;

    offer() //往队列添加元素如果队列已满直接返回false,队列未满则直接插入并返回true;

    add() //对offer()方法的简单封装.如果队列已满,抛出异常new IllegalStateException("Queue full");

    删除元素

    remove() //方法直接删除队头的元素;

    take() //取出并删除队头的元素,当队列为空,则会一直等待直到队列有新元素可以取出,或者线程被中断抛出异常;

    pool() //取出并删除队头的元素,当队列为空,返回null;

    peek() //直接取出队头的元素,并不删除;

    element() //对peek方法进行简单封装,如果队头元素存在则取出并不删除,如果不存在抛出异常NoSuchElementException();

  4. 基于内存的队列,队列的大小依赖于JVM内存的大小,一般如果是内存占用不大且处理相对较为及时的都可以采用此种方法。如果你在队列处理的时候需要有失败重试机制,那么用此种队列就不是特别合适了,可以使用基于数据库的mq。

  5. 使用示例,简单模仿基于生产者、消费者、消息队列模型的内存mq

*生产者模型

    public class Produce {

	private int id ;

	private BlockingQueue<String> queue;

	public Produce() {
}
public Produce(int id, BlockingQueue<String> queue) {
this.id = id;
this.queue = queue;
System.out.println("创建了生产者"+ id + "号");
} public void produce(String message){
boolean add = this.queue.add(message);
if(add){
System.out.println("生产者"+id+"号,生产了一条消息,"+message);
}
}
}

*消费者模型

public class Consumer {

	private int id;

	private BlockingQueue<String> queue;

	private static ScheduledExecutorService  executors = Executors.newScheduledThreadPool(1);

	public Consumer() {
} public Consumer(BlockingQueue<String> queue, int id){
this.id = id;
this.queue = queue;
System.out.println("创建了消费者:" + id +"号");
consumer();
}
public void consumer(){ executors.scheduleWithFixedDelay(new Runnable() {
@Override
public void run() {
System.out.println("消费者手里的线程池核武器收到了一个命令,此时队列中的任务数"+queue.size()+"个");
try {
String message = queue.take();
System.out.println("消费者: " + id + "号,开始消费了");
Thread.sleep(3000);
System.out.println("消费者: " + id + "消费结束了,"+message);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, 0, 5, TimeUnit.SECONDS); }
}

*测试类

public class Test {

	public static void main(String[] args) {
LinkedBlockingDeque<String> queue = new LinkedBlockingDeque<>(1000);
Produce produce = new Produce(1, queue);
new Consumer(queue, 1);
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
for(int i=0;i<20;i++){
produce.produce("@"+i+"@");
}
}
}

ps:消息队列无论在分布式还是在高并发概念中,都是一个非常重要的数据处理方式,本文只是我对消息中间件这个技术栈的第一次试水,后面会陆续增加基于数据库的mq,以及现在已经比较成熟商业中间件产品rabbitmq、rocketmq等的学习笔记。

java-消息中间件-基于内存的mq的更多相关文章

  1. 消息中间件(一)MQ详解及四大MQ比较

    一.消息中间件相关知识 1.概述 消息队列已经逐渐成为企业IT系统内部通信的核心手段.它具有低耦合.可靠投递.广播.流量控制.最终一致性等一系列功能,成为异步RPC的主要手段之一.当今市面上有很多主流 ...

  2. Java中堆内存和栈内存详解2

    Java中堆内存和栈内存详解   Java把内存分成两种,一种叫做栈内存,一种叫做堆内存 在函数中定义的一些基本类型的变量和对象的引用变量都是在函数的栈内存中分配.当在一段代码块中定义一个变量时,ja ...

  3. Java中堆内存和栈内存详解

    Java把内存分成两种,一种叫做栈内存,一种叫做堆内存 在函数中定义的一些基本类型的变量和对象的引用变量都是在函数的栈内存中分配.当在一段代码块中定义一个变量时,java就在栈中为这个变量分配内存空间 ...

  4. RDD:基于内存的集群计算容错抽象(转)

    原文:http://shiyanjun.cn/archives/744.html 该论文来自Berkeley实验室,英文标题为:Resilient Distributed Datasets: A Fa ...

  5. 高性能、高容错、基于内存的开源分布式存储系统Tachyon的简单介绍

    Tachyon是什么? Tachyon是一个高性能.高容错.基于内存的开源分布式存储系统,并具有类Java的文件API.插件式的底层文件系统.兼容Hadoop MapReduce和Apache Spa ...

  6. java优化占用内存的方法(一)

    java做的系统给人的印象是什么?占 内存!说道这句话就会有N多人站出来为java辩护,并举出一堆的性能测试报告来证明这一点.其实从理论上来讲java做的系统并不比其他语言开发出来的 系统更占用内存, ...

  7. java程序的内存分配

    java程序的内存分配 JAVA 文件编译执行与虚拟机(JVM)介绍 Java 虚拟机(JVM)是可运行Java代码的假想计算机.只要根据JVM规格描述将解释器移植到特定的计算机上,就能保证经过编译的 ...

  8. Java运行时内存划分

    这篇文章可以说是摘抄自周志明的<深入理解Java虚拟机>,但是加上了自己的理解,印象可以更深些. Java虚拟机在执行Java程序的时候会把他所管理的内存划分为若干个不同的数据区域,各个区 ...

  9. RDD:基于内存的集群计算容错抽象

    转载自:http://shiyanjun.cn/archives/744.html 摘要 本文提出了分布式内存抽象的概念--弹性分布式数据集(RDD,Resilient Distributed Dat ...

随机推荐

  1. Struts2 前台显示问题

    遇到的问题: 查询字段相同值的和的时候用到了sum函数,导致和实体类的不一样,无法取到. 开始的时候的代码. ; 这样的话SUM(o_count)无法显示. 我想把SUM(o_count)设置为实体类 ...

  2. Tecplot: Legend和图像中 Dashed/Dash dot/Long dash 等虚线显示没有区别的问题

    问题描述:如下图1中线型明明选择的不同,但是tecplot里显示的图像和legend里显示的线型没有区别,应该是bug. tecplot 版本:360EX  2017R2 解决办法:把Pattern ...

  3. 【EMV L2】终端风险管理(Terminal Risk Management)

    终端风险管理使大额交易联机授权,并确保芯片交易能够周期性地进行联机以防止在脱机环境中也许无法察觉的风险. 虽然发卡行被强制要求在应用交互特征(AIP)中将终端风险管理位设置成1以触发终端风险管理,但终 ...

  4. Unity3D实现多语言切换

    项目现在需要做多语言切换部分,下面是一个基本多语言切换实现 1. 首先建立一个类来存放字符,其中包括一个静态方法来根据Key和语言类型获取对应字符 using System.Collections; ...

  5. Golang微服务:Micro介绍

    官方文档地址 https://micro.mu/docs/index.html Tookit API HTTP接入网关.反向代理或将HTTP转为RPC请求调用后端服务 Web 一个web应用程序,默认 ...

  6. 代码中设置color的selector

    //应该用getColorStateList这种方式 xml中设置时直接color引用就可以了 textView.setTextColor(getResources().getColorStateLi ...

  7. leetcode 764.Largest Plus Sign

    根据题意的话就是在非0的地方开始寻找上下左右分别能够走到的最大步长的. 那么使用暴力的方法竟然leetcode还是给过了. class Solution { public: int orderOfLa ...

  8. mybatis:Parameter 'ids' not found.

    https://www.cnblogs.com/baby-lijun/p/5908088.html ps:根本原因就是他们根本就没有理解foreach里面的collection应该放什么东西,错误的理 ...

  9. SpringSecurity身份验证基础入门

    对于没有访问权限的用户需要转到登录表单页面.要实现访问控制的方法多种多样,可以通过Aop.拦截器实现,也可以通过框架实现(如:Apache Shiro.Spring Security). pom.xm ...

  10. 查看那些进程使用了swap

    https://blog.csdn.net/xiangliangyu/article/details/8213127$ sudo pacman -S iotop https://blog.longwi ...