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. ZT 将sublime text的tab改为四个空格

    打开Sublime Text3,选择菜单Preferences->Settings-User,打开用户配置文件(据本人理解,Settings-Default是不允许用户自己修改的~而Settin ...

  2. Flask-----Flask里引用哈希密码

    哈希密码(Password Hash): 对口令进行一次性的加密处理而形成的杂乱字符串.这个加密的过程被认为是不可逆的,也就是说,人们认为从哈希串中是不可能还原出原口令的.(这句话是比较官方的解释). ...

  3. Day01_Python学习今日收获

    1.关键字 break:终止本层循环,即如果是双层嵌套循环,那么就终结最内层循环 注意:如果在for或while循环中终止,他们任何对应的else语句块也将不执行. 2.关键字continue:跳过当 ...

  4. SharePoint 2013 新特性 (三) 破改式 —— 设计管理器的使用 [1.设备通道]

    首先,哥们儿们会问,为啥要有设计管理器呢,不是原来就可以编辑页面了么,原来那个编辑不了模板页和布局页,也不能打包,而且也看不到具体HTML代码,不能编辑CSS,当然,你安装的SharePoint De ...

  5. 【转】干货 | 【虚拟货币钱包】从 BIP32、BIP39、BIP44 到 Ethereum HD Wallet

    虚拟货币钱包 钱包顾名思义是存放$$$.但在虚拟货币世界有点不一样,我的帐户资讯(像是我有多少钱)是储存在区块链上,实际存在钱包中的是我的帐户对应的 key.有了这把 key 我就可以在虚拟货币世界证 ...

  6. php 品牌全车零件订购平台( 带采集数据 及 账号自动登陆【已绕过https证书加密】,php源码 ,QQ: 876635409 )

    php捷豹路虎 品牌全车零件订购平台  ( 带采集数据 及 账号自动登陆[已绕过https证书加密],php源码 ,QQ: 876635409 [由于咨询用户太多,请备注:汽车配件]) 一.php+m ...

  7. Team416

    软件工程小组今天成立了! 成员:计科1704 杨璐华 俞天耀 杨通玉 王旭 分工:  项目经理: 杨璐华 需求分析: 俞天耀 运行维护: 杨通玉 软件架构: 王旭 我们团队关于此次软件工程项目的分工大 ...

  8. ReentrantLock+线程池+同步+线程锁

    1.并发编程三要素? 1)原子性 原子性指的是一个或者多个操作,要么全部执行并且在执行的过程中不被其他操作打断,要么就全部都不执行. 2)可见性 可见性指多个线程操作一个共享变量时,其中一个线程对变量 ...

  9. 创建GitHub仓库并与本地Git绑定

    由于工作要使用GitLab,这里总结并实际操作使用一下Git. 大家都知道,Git是Linux支之父Linus Torvalds编写的一个版本控制软件.目前我们接触的与Git有关系的有三种,分别是Gi ...

  10. mysql技巧:按条件筛选,然后替换

    1.按条件筛选,然后替换 select * from phome_ecms_tv where playurl like '%关键词%';update phome_ecms_tv set myorder ...