java观察者模式

import java.util.Observable;
import java.util.Observer;

继承Observable类的被称为被观察者;

实现Observer接口的被称为观察者;

观察者代码:

package com.gxhc.alarm.listener;

import java.util.Map;
import java.util.Observable;
import java.util.Observer;

import com.gxhc.alarm.service.AlarmService;
import com.gxhc.alarm.table.entity.AlarmLog;
import com.gxhc.util.ConstantUtil;
import com.gxhc.util.ContextUtil;

public class QueueWatcher implements Observer{
	
    public QueueWatcher(Observable o){
        o.addObserver(this);
    }
    
    public QueueWatcher(){}
    
    
    
        /* (非 Javadoc)
        * 
        * 观察者只被触发一次,后续消息的推送由队列维护
        * @param o 被观察者
        * @param arg
        * @see java.util.Observer#update(java.util.Observable, java.lang.Object)
        */
        
    @Override
    public void update(Observable o, Object arg) {
    	//通过定长java线程池执行该操作,防止无限启动线程导致程序卡死。
    	ConstantUtil.alarmFixedThreadPool.execute(new Runnable() {
			
			@Override
			public void run() {
				try {
					// TODO Auto-generated method stub
					ConstantUtil.IsGeginQueue = true;
					
					AlarmService alarmService = ContextUtil.getBean("alarmService",AlarmService.class);
					while (ConstantUtil.IsGeginQueue) {
						//如果阻塞队列中无元素可取,则线程进入阻塞状态,直到该队列中再次拥有元素时,激活。
						//AlarmLog alarmLog = (AlarmLog)ConstantUtil.alarmQueue.take();
						Map<String, Object> map = (Map<String, Object>)ConstantUtil.alarmQueue.take();
						alarmService.insertMessage((AlarmLog)map.get("alarmLog"),String.valueOf(map.get("reciveUser")),String.valueOf(map.get("reciverDept")),String.valueOf(map.get("cid")));
					}
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		});
    	
    	
    	
		/*ConstantUtil.alarmFixedThreadPool.execute(new Runnable() {
			
			@Override
			public void run() {
				try {
					AlarmLog alarmLog = (AlarmLog)ConstantUtil.alarmQueue.take();
					AlarmService alarmService = ContextUtil.getBean("alarmService",AlarmService.class);
					// TODO Auto-generated method stub
					alarmService.setMessage(alarmLog,null,null);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		});*/
		
		// 触发订阅处理
		//alarmService.setMessage(((AlarmService)o).getAlarmLog(),null,null);
		
    }

}

被观察者:在方法addRecord() 通过调用notify(alarmLog);触发观察者

package com.gxhc.alarm.service;

import java.util.HashMap;
import java.util.Map;
import java.util.Observable;
import java.util.concurrent.TimeUnit;

import com.gxhc.alarm.mapper.AlarmExtendMapper;
import com.gxhc.alarm.mapper.AlarmSubscribeExtendMapper;
import com.gxhc.alarm.mapper.AlarmSubscribeUserExtendMapper;
import com.gxhc.alarm.table.entity.AlarmLog;
import com.gxhc.alarm.table.mapper.AlarmLogMapper;
import com.gxhc.alarm.table.mapper.AlarmLogReciverMapper;
import com.gxhc.alarm.table.mapper.AlarmMessageLogMapper;
import com.gxhc.alarm.table.mapper.AlarmTypeMapper;
import com.gxhc.system.system.mapper.UserExtendMapper;
import com.gxhc.system.system.table.mapper.UserMapper;
import com.gxhc.system.system.table.mapper.UserRoleMapper;
import com.gxhc.util.ConstantUtil;

public class AlarmService extends Observable{

	private AlarmLogMapper alarmLogMapper;
	private AlarmLogReciverMapper alarmLogReciverMapper;
	private AlarmMessageLogMapper alarmMessageLogMapper;
	private AlarmExtendMapper alarmExtendMapper;
	private AlarmSubscribeExtendMapper alarmSubscribeExtendMapper;
	private AlarmTypeMapper alarmTypeMapper;
	private AlarmLog alarmLog;
	private UserRoleMapper userRoleMapper;
	private UserMapper userMapper;
	private AlarmSubscribeUserExtendMapper alarmSubscribeUserExtendMapper;
	
	private AppPushService appPushService;
	private EmailPushService emailPushService;
	private NotePushService notePushService;
	private SystemPushService systemPushService;
	private UserExtendMapper userExtendMapper;
	
	/**
	 * 
	 * @param token 注册token
	 * @param key 注册id
	 * @param alarmLog 告警信息
	 * @param state 信息状态 1:告警消息;2:恢复消息
	 * @param reciveUser接受用户
	 * @param reciverDept 接受组织机构
	 * @return
	 * @throws InterruptedException 
	 */
	public int addRecord (AlarmLog alarmLog,int state,String reciveUser,String reciverDept) throws InterruptedException{
		
		
		
		// 订阅处理  deleted by sl 重复,下面会触发观察者。
		//setMessage(alarmLog,reciveUser,reciverDept);
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("alarmLog", alarmLog);
		map.put("reciveUser", reciveUser);
		map.put("reciverDept", reciverDept);
		map.put("cid", 1);
		//写入队列
		ConstantUtil.alarmQueue.offer(map, 2, TimeUnit.SECONDS);
		
		// 触发观察者
		//notify(alarmLog);
		
		// 首次进入,触发观察者,后续的消息只需放到队列中,程序自动维护消息推送
		if(!ConstantUtil.IsGeginQueue){
			notify(alarmLog);
		}
		
		
		// 返回接口状态信息
		return 2;
	};
	
	// 观察者
	private void notify(AlarmLog alarmLog) {
		if (alarmLog != null) {
			this.alarmLog = alarmLog;
			super.setChanged();
		}
		
		super.notifyObservers();
	};
	
	
	
}

 

当然观察者可以观察被观察者,前提是他们两个被关联了起来:setWatcher();

package com.gxhc.alarm.listener;

import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

import com.gxhc.alarm.service.AlarmService;
import com.gxhc.alarm.listener.QueueWatcher;
import com.gxhc.util.ConstantUtil;
import com.gxhc.util.ContextUtil;

public class QueueListener implements ServletContextListener {

	/**
	 * 初始化加载
	 */
	@Override
	public void contextInitialized(ServletContextEvent arg0) {
		setQueue();
		setWatcher();
		setFixedThreadPool();
	}
	
	//初始化队列
	public void setQueue(){
		ConstantUtil.alarmQueue = new LinkedBlockingQueue<Object>(10000);
	}

	//初始化被观察者
	public void setWatcher(){
		//modify by sl 原来的被观察者,不是上下文中的alarmService ,无法触发观察者事件
		//ConstantUtil.alarmService = new AlarmService();
		ConstantUtil.alarmService = ContextUtil.getBean("alarmService",AlarmService.class);
		QueueWatcher queueWatcher = new QueueWatcher(ConstantUtil.alarmService);
	}
	
	//初始化线程池
	public void setFixedThreadPool(){
		// 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
		ConstantUtil.alarmFixedThreadPool = Executors.newFixedThreadPool(10); 
	}
	@Override
	public void contextDestroyed(ServletContextEvent arg0) {
	}
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java观察者模式是一种常见的设计模式,用于在对象之间建立一对多的依赖关系[^1]。在该模式,有一个主题(被观察者)和多个观察者。当主题的状态发生变化时,它会通知所有的观察者进行相应的更新。 下面是一个Java观察者模式的示例代码: ```java // 定义观察者接口 public interface Observer { void update(); } // 定义具体的观察者类 public class ConcreteObserver implements Observer { private int observerState; private ConcreteSubject subject; public ConcreteObserver(ConcreteSubject subject) { this.subject = subject; this.subject.registerObserver(this); } @Override public void update() { observerState = subject.getState(); System.out.println("Observer state updated: " + observerState); } } // 定义主题接口 public interface Subject { void registerObserver(Observer observer); void removeObserver(Observer observer); void notifyObservers(); } // 定义具体的主题类 public class ConcreteSubject implements Subject { private int state; private List<Observer> observers = new ArrayList<>(); public int getState() { return state; } public void setState(int state) { this.state = state; notifyObservers(); } @Override public void registerObserver(Observer observer) { observers.add(observer); } @Override public void removeObserver(Observer observer) { observers.remove(observer); } @Override public void notifyObservers() { for (Observer observer : observers) { observer.update(); } } } // 使用观察者模式 public class Main { public static void main(String[] args) { ConcreteSubject subject = new ConcreteSubject(); ConcreteObserver observer1 = new ConcreteObserver(subject); ConcreteObserver observer2 = new ConcreteObserver(subject); subject.setState(10); // 输出: // Observer state updated: 10 // Observer state updated: 10 subject.setState(20); // 输出: // Observer state updated: 20 // Observer state updated: 20 } } ``` 在上面的示例,`ConcreteSubject`是具体的主题类,它维护了一个观察者列表,并在自身状态发生变化时通知所有观察者进行更新。`ConcreteObserver`是具体的观察者类,它实现了`Observer`接口,并在`update`方法更新自己的状态。 使用观察者模式可以实现对象之间的松耦合,当一个对象的状态发生变化时,不需要直接调用其他对象的方法,而是通过观察者模式来通知其他对象进行更新。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值