在做的项目中,常常用到的"wait-notifyAll"实例
package com.ireal.crpas.qos.QoSPerformanceAnalyzeSrv.processor;
import java.util.ArrayList;
import java.util.List;
import com.ireal.crpas.qos.QoSPerformanceAnalyzeSrv.analyzer.DeviceManage;
import com.ireal.crpas.qos.QoSPerformanceAnalyzeSrv.analyzer.MonitorPoint;
import com.ireal.crpas.qos.struct.QoSDataInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/*
* 信息数据接收和处理
*/
public class DataReceiver extends Thread {
public Logger logger = LoggerFactory.getLogger(getClass());
private static DataReceiver instance = null;
public static DataReceiver getInstance()
{
if (instance == null)
{
instance = new DataReceiver();
}
return instance;
}
public DataReceiver() {
this.setName("CRPAS_QoSPerformanceAnalyzeSrv_DataReceiver");
dataQueue = new DataQueue();
}
/**
* 消息队列
*/
private DataQueue dataQueue;
private boolean blRuning = false;
public boolean isRun()
{
return this.blRuning;
}
@Override
public void run() {
this.blRuning = true;
while (blRuning) {
try
{
//取数据并处理
QoSDataInfo msg = getDataInfo();
String mpid = msg.getNodeId();//监控点id 、根据监控点id查出监控点的信息及设备信息及上下限信息
MonitorPoint momnitorPoint = DeviceManage.getInstance().getMomnitorPoint(mpid);
// TODO:对数据进行分析处理,生成/结束告警
// logger.info("开始分析处理");
momnitorPoint.generateAlarm(msg);
Thread.sleep(10);
}
catch (java.lang.Throwable e)
{
e.printStackTrace();
}
finally
{
}
if (blRuning == false)
{
if (this.dataQueue.getNum() == 0)
{
break;
}
}
}
cleanUp();
}
public void stopThread(){
blRuning = false;
instance = null;
}
/**
* 清理
*/
private void cleanUp()
{
DataReceiver.instance = null;
}
protected void finalize() throws java.lang.Throwable
{
cleanUp();
super.finalize();
}
/**
* 数据处理过程
* @param datas 待数据
*/
public void processAlarmMsg(List<QoSDataInfo> datas)
{
dataQueue.put(datas);//将数据放入消息队列
}
/*
* 从数据队列中取得一个待处理的消息,如果没有消息将挂起线程直到有数据出现
* 取出后数据自动从队列中清除
* @return 数据对象
*/
private QoSDataInfo getDataInfo()
{
QoSDataInfo dataInfo = null;
while (true)
{
synchronized (this.dataQueue)
{
dataInfo = (QoSDataInfo) dataQueue.get();
if (dataInfo == null)
{
try
{
dataQueue.wait();
}
catch (InterruptedException x)
{
}
}
else
{
if (instance.dataQueue.getNum() > 0)
{
// System.out.print("g." + instance.dataQueue.getNum());
}
break;
}
}
}
return dataInfo;
}
public void printMsgNum()
{
System.out.println("队列中未处理消息数目为:" + Integer.toString(dataQueue.getNum()));
}
}
/**
* <p>Title: 性能数据队列</p>
* <p>Description: </p>
* <p>Copyright: Copyright (c) 2019</p>
* <p>Company: 北京世纪瑞尔技术股份公司</p>
* @author gms
* @version 1.0
*/
class DataQueue
{
private List<QoSDataInfo> list = new ArrayList<QoSDataInfo>();
/**
* 添加新元素到队列
* @param obj 待加入元素
*/
public void put(Object obj)
{
synchronized (this)
{
list.add((QoSDataInfo)obj);
notifyAll();
}
}
public void put(List<QoSDataInfo> statusMsgs)
{
synchronized (this)
{
list.addAll(statusMsgs);
notifyAll();
}
}
/**
* 得到最早加入队列的一个元素
* @return 最早加入队列的一个元素
*/
public Object get()
{
if (list.isEmpty())
{
return null;
}
else
{
return list.remove(0);
}
}
/**
* 取得队列的消息数目
* @return 队列中对象的数目
*/
public int getNum()
{
return list.size();
}
}
此线程一直在跑
调用
啊啊
此线程一直在运转调用getdatainfo从内部类dataqueeue中取数据,若取到的数据对象为null,那么则等待,直到外部有调用put方法传入数据时,再唤醒全部的线程继续执行。
外部调用方法这也是生产-消费的一个模式。 外部回调不断的通过方法传来数据,此线程不断的对传进来的数据进行解析。