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. C语言---指针变量详解1

    数据在内存中的地址也称为指针,如果一个变量存储了一份数据的指针,我们就称它为指针变量.在C语言中,允许用一个变量来存放指针,这种变量称为指针变量.指针变量的值就是某份数据的地址,这样的一份数据可以是数 ...

  2. c# 在.NET使用Newtonsoft.Json转换,读取,写入json

    转自:http://blog.sina.com.cn/s/blog_70686f3a0101kemg.html  首先,大家要明白什么是json,了解更多关于json方面资料大家可以点击https:/ ...

  3. 12_jvm性能优化专题1——top命令和jstack联合定位

    一:异常项目构建 1.通过while死循环构造异常常见: package com.huawei.jvm; import org.springframework.stereotype.Controlle ...

  4. C#引用C++的DLL方案(C#调用非托管动态链接库)

    SocketClientInit是C++里面定义的方法,通过EntryPoint = "?SocketClientInit@@YAHHHPAD@Z"指出这个函数的真正入口处,方法是 ...

  5. 几个NAND/NOR门可以表示一个XOR门?

    这段时间就是在看测试相关的东西,无意之中发现了ISCAS85中有个名词EXOR,愣了一下反应过来应该还是异或门,毕竟叫exclusive-OR gate,其中文档中还提到了一句一个异或门可以由四个与非 ...

  6. 12集合(2)-----Set

    一.总体分类 Collection(包括方法add,remove,contains,clear,size) List(接口) LinkedList ArrayList Vector---Stack 2 ...

  7. JavaScript权威指南--数组Array

    什么是数组 数组是值的有序集合.每一个值叫做元素,每一个元素在数组中有一个位置,用数字表示,称为索引.js数组是无类型的.动态的,也可能是稀疏的.每个数组都有length属性.数组最大能容纳42949 ...

  8. html5 知识点简单总结03

    table表格 ----基本结构 table默认无边框(border) <table border="数值"> <tr> <th>表头</ ...

  9. sublime An unhandled OS error was encountered nodejspath_error

    sublime An unhandled OS error was encountered  nodejspath_error 点击ok,修改node_path typescript 插件下载 ctr ...

  10. sklearn pipeline

    sklearn.pipeline pipeline的目的将许多算法模型串联起来,比如将特征提取.归一化.分类组织在一起形成一个典型的机器学习问题工作流. 优点: 1.直接调用fit和predict方法 ...