告警系统架构如下

1、 数据处理系统处理完原始数据并入库后,发送消息到kafka系统;

2、 告警生产者从kafka系统查询消息存入告警消息队列;

3、 告警消费者从告警消息队列查询消息进行处理。

这显然是生产者消费者模型,一个告警消息生产者,多个告警消息消费者。生产者生产消息过快会产生消息积压,生产者生产消息过慢不能充分利用硬件资源。所以必须要生产者和消费者协同处理,使得系统充分利用。具体做法是消息队列为空时,消费者通知生产者生产消息,生产者生产好消息后,通知消费者处理消息。Java中我们使用的对象锁以及wait/notify方法进行线程通信,原理如下:

生产者——循环(获取锁synchronized,释放锁wait(等待被唤醒),生产消息)

消费者——循环(获取锁,消息空则notify/消息不空则消费消息)

消息队列代码:

package com.coshaho.threadpool;

import java.util.ArrayList;
import java.util.List; /**
* 消息队列
* @author coshaho
*/
public class MessageQueue
{
List<String> messageList = new ArrayList<String>(); public boolean isEmpty()
{
return messageList.isEmpty();
} /**
* 消费消息
* @return
*/
public String consumeMessage()
{
return messageList.remove(0);
} /**
* 生产消息
* @param msg
*/
public void produceMessage(String msg)
{
messageList.add(msg);
}
}

消费者代码:

package com.coshaho.threadpool;

/**
* 消费者,消息队列为空则唤醒生产者
* @author h00219638
*
*/
public class Customer implements Runnable
{
String name;
MessageQueue msgQueue;
public Customer(String name, MessageQueue msgQueue)
{
this.name = name;
this.msgQueue = msgQueue;
} @Override
public void run()
{
while(true)
{
// 消费消息
synchronized(msgQueue)
{
// 如果消息队列为空,唤醒生产者生产消息
if(msgQueue.isEmpty())
{
msgQueue.notify();
}
// 消息队列不为空,则消费消息
else
{
String msg = msgQueue.consumeMessage();
System.out.println("Customer " + name + " consumed message: " + msg + ".");
}
}
try
{
Thread.sleep(1000);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
}

生产者代码:

package com.coshaho.threadpool;

/**
* 生产者,消息队列为空时,消费者会唤醒生产者生产消息
* @author coshaho
*/
public class Producer implements Runnable
{
String name;
MessageQueue msgQueue;
public Producer(String name, MessageQueue msgQueue)
{
this.name = name;
this.msgQueue = msgQueue;
} @Override
public void run()
{
int i = 0;
while(true)
{
synchronized(msgQueue)
{
try
{
// 释放msgQueue的锁,等待消费者唤醒
msgQueue.wait();
}
catch (InterruptedException e)
{
e.printStackTrace();
}
// 唤醒后生产消息
for(int j = 0; j < 5; j++)
{
msgQueue.produceMessage("message_" + i + "_" + j);
}
}
System.out.println("Producer " + name + " produced 5 messages.");
}
} }

消息处理进程代码:

package com.coshaho.threadpool;

/**
* 消息处理中心
* @author coshaho
*/
public class MessageProcessCenter
{
public static void main(String[] args)
{
// 初始化消息队列
MessageQueue msgQueue = new MessageQueue();
// 运行1个生产者
new Thread(new Producer("Producer", msgQueue)).start(); // 运行3个消费者
new Thread(new Customer("Customer1", msgQueue)).start();
new Thread(new Customer("Customer2", msgQueue)).start();
new Thread(new Customer("Customer3", msgQueue)).start();
}
}

运行结果:

Producer Producer produced 5 messages.
Customer Customer2 consumed message: message_0_0.
Customer Customer3 consumed message: message_0_1.
Customer Customer2 consumed message: message_0_2.
Customer Customer1 consumed message: message_0_3.
Customer Customer3 consumed message: message_0_4.
Producer Producer produced 5 messages.
Customer Customer3 consumed message: message_0_0.
Customer Customer1 consumed message: message_0_1.
Customer Customer2 consumed message: message_0_2.
Customer Customer1 consumed message: message_0_3.
Customer Customer3 consumed message: message_0_4.
Producer Producer produced 5 messages.
Customer Customer3 consumed message: message_0_0.
Customer Customer1 consumed message: message_0_1.
Customer Customer2 consumed message: message_0_2.
Customer Customer3 consumed message: message_0_3.
Customer Customer1 consumed message: message_0_4.

生产者消费者模型——wait/notify/notifyAll使用的更多相关文章

  1. 如何在 Java 中正确使用 wait, notify 和 notifyAll – 以生产者消费者模型为例

    wait, notify 和 notifyAll,这些在多线程中被经常用到的保留关键字,在实际开发的时候很多时候却并没有被大家重视.本文对这些关键字的使用进行了描述. 在 Java 中可以用 wait ...

  2. 多线程-4.wait() notify() notifyAll() 生产者消费者模型

    1.wait()方法 该方法继承于Object类.在调用obj.wait()方法后,当前线程会失去obj的锁.待其他线程调用obj.notify()或notifyAll()方法后进入锁等待池,争抢到锁 ...

  3. java线程基础巩固---多线程下的生产者消费者模型,以及详细介绍notifyAll方法

    在上一次[http://www.cnblogs.com/webor2006/p/8419565.html]中演示了多Product多Consumer假死的情况,这次解决假死的情况来实现一个真正的多线程 ...

  4. 多线程学习-基础(十二)生产者消费者模型:wait(),sleep(),notify()实现

    一.多线程模型一:生产者消费者模型   (1)模型图:(从网上找的图,清晰明了) (2)生产者消费者模型原理说明: 这个模型核心是围绕着一个“仓库”的概念,生产者消费者都是围绕着:“仓库”来进行操作, ...

  5. 第23章 java线程通信——生产者/消费者模型案例

    第23章 java线程通信--生产者/消费者模型案例 1.案例: package com.rocco; /** * 生产者消费者问题,涉及到几个类 * 第一,这个问题本身就是一个类,即主类 * 第二, ...

  6. Java多线程14:生产者/消费者模型

    什么是生产者/消费者模型 一种重要的模型,基于等待/通知机制.生产者/消费者模型描述的是有一块缓冲区作为仓库,生产者可将产品放入仓库,消费者可以从仓库中取出产品,生产者/消费者模型关注的是以下几个点: ...

  7. Java生产者消费者模型

    在Java中线程同步的经典案例,不同线程对同一个对象同时进行多线程操作,为了保持线程安全,数据结果要是我们期望的结果. 生产者-消费者模型可以很好的解释这个现象:对于公共数据data,初始值为0,多个 ...

  8. Java实现多线程生产者消费者模型及优化方案

    生产者-消费者模型是进程间通信的重要内容之一.其原理十分简单,但自己用语言实现往往会出现很多的问题,下面我们用一系列代码来展现在编码中容易出现的问题以及最优解决方案. /* 单生产者.单消费者生产烤鸭 ...

  9. 【1】【JUC】Condition和生产者消费者模型

    本篇文章将介绍Condition的实现原理和基本使用方法,基本过程如下: 1.Condition提供了await()方法将当前线程阻塞,并提供signal()方法支持另外一个线程将已经阻塞的线程唤醒. ...

随机推荐

  1. 【BZOJ5090】组题 分数规划

    [BZOJ5090]组题 Description 著名出题人小Q的备忘录上共有n道可以出的题目,按照顺序依次编号为1到n,其中第i道题目的难度系数被小Q估计为a_i,难度系数越高,题目越难,负数表示这 ...

  2. SVG学习笔录(一)

    SVG可缩放矢量图形(Scalable Vector Graphics)这项技术,现在越来越让大家熟知,在h5的移动端应用使用也越来越广泛了, 下面让我分享给大家svg学习的经验. HTML体系中,最 ...

  3. java使用AES256解密

    网上关于java用AES加密解密的文章有很多,我这里只用到解密(加密是服务器那边做^_^),所以更简洁一些: public class AES256Utils { private static fin ...

  4. ImageGrab.grab()全屏抓取错误

    前几天看见知乎上的连连看外挂就想着自己试一下 但是搞了半天发现截取全屏的图片就出现了问题 截取的图片其实只有屏幕左上角的一部分 大概就这样: 用的是PIL  ImageGrab里的grab函数 没加参 ...

  5. 《机器学习实战》第3章决策树程序清单3-1 计算给定数据集的香农熵calcShannonEnt()运行过程

    from math import log def calcShannonEnt(dataSet): numEntries = len(dataSet) print("样本总数:" ...

  6. git push 文件过大时出错,fatal: The remote end hung up unexpectedly

    可以修改配置文件: 1 使用命令:git config http.postBuffer = 524288000 2修改git文件夹中的config文件,加入如下一段: [http] postBuffe ...

  7. linux中vim常用命令

    vim工作模式 vi 文件名 进入命令模式 i a o 进入插入模式 ESC键 回到命令模式 : 进入编辑模式 添加行号 :set number/nu :wq 保存退出 插入命令 a 在光标所在字符后 ...

  8. SQL Server 登录名、服务器角色、用户名和数据库角色 --- 解释

    一.基本解释 登录名:登录服务器的用户账号: 服务器角色:登录名对该服务器具有的权限,角色分多种的,一个角色可以有多个登录名,如操作系统的系统用户可以有多个. SQL服务器角色  sysadmin   ...

  9. mysql 记录的增删改查

    MySQL数据操作: DML ======================================================== 在MySQL管理软件中,可以通过SQL语句中的DML语言 ...

  10. Python3学习之路~2.1 列表、元组操作

    列表 列表是我们以后最常用的数据类型之一,通过列表可以对数据实现最方便的存储.修改等操作. 定义列表(list) names=['Amy','Bob','Cindy','David'] 通过下标访问列 ...