`
Tonyguxu
  • 浏览: 281451 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

WXXR LRUMap的实现

 
阅读更多

前言

实现LRU算法,注意观察者模式、并发(读写锁、线程池)的运用

核心类:LRUMap

成员变量

LinkedHashMap<K,V> map —— 底层存放元素( key-value )的容器。

ConcurrentLinkedQueue<LRUMapEvictionListener<K,V>> listeners —— 监听器队列,存放注册到该LRUMap的所有监听器(通过 LRUMap的 addListener注册 ),具体监听器实现 LRUMapEvictionListener接口,实现void objectEvicted(K key, V value)方法(对象逐出处理程序,详见  )。当执行LRUMap的evict、setCapacity、put操作时,会notify listener,并由线程池中的线程来遍历 listeners 执行各个监听器的处理程序(即 objectEvicted )。

 

ExpirationProcessor exProcess —— 内部类,线程类(继承Thread,是个守护线程setDaemon(true)),唤作“阎王线程”。持有成员属性Map<Object,Long> expirations唤作“死亡手册”(放置了key和lastAccess最后访问时间)和long expireTime(构造阎王线程实例时候设置的存活时间)。 “阎王线程”会不断地定时地检查死亡名单,如果名单中某个元素达到死亡时间(当前时间 - lastAccess > expireTime),则将该元素从名单 容器 中删除并notify listener做相应处理操作。

 

“阎王线程”何时新建、start呢?

在实例化LRUMap的时候,会根据设置的存活时间 expireTime决定是否启动“阎王线程”,如果实例化LRUMap时不指定 expireTime 或者设置为0,则不会有人定期检查容器中的元素是否到了死亡时间了。

if(expired > 0){
            exProcess = new ExpirationProcessor(this,expired*1000L);
            exProcess.start();
        }
 

 

ThreadPoolExecutor poolExecutor ——线程池用于异步执行监听器处理程序。在调用LRUMap构造的时候实例化。

 

poolExecutor = new ThreadPoolExecutor(1,10,120L,TimeUnit.SECONDS,
    			new LinkedBlockingQueue<Runnable>(),
    			new ThreadFactoryImpl(null,"LRUMap Listener Thread")
    			);

poolExecutor.execute(new Runnable() {		
			public void run() {
				doNotifyListeners(rmKey,rmVal);
			}
		});

 

ReadWriteLock readWriteLock = new ReentrantReadWriteLock() ——通过readLock()和writeLock()可以获得读锁和写锁。

 

内部类

private static class ExpirationProcessor extends Thread —— “阎王线程”类,在run()方法里while(true)体,会不断地定期地(每隔10s)检查死亡名单,将达到死亡时间的成员“干掉”。

 

将key及对应的最近访问时间放到阎王线程持有的死亡名单expirations里

public Long put(Object key, Long value) {
            return expirations.put(key, value);
        }
  

构造方法

 

public LRUMap(int size) —— expired存活时间默认为0

public LRUMap(int size,int expired)

public LRUMap(int size,int expired) {
        if(size <= 0){
            throw new IllegalArgumentException("Size should larger than 0");
        }
        map = new LinkedHashMap<K,V>(size);
        this.capacity = size;
        listeners = new ConcurrentLinkedQueue<LRUMapEvictionListener<K,V>>();  
        poolExecutor = new ThreadPoolExecutor(1,10,120L,TimeUnit.SECONDS,
    			new LinkedBlockingQueue<Runnable>(),
    			new ThreadFactoryImpl(null,"LRUMap Listener Thread")
    			);
        if(expired > 0){
            exProcess = new ExpirationProcessor(this,expired*1000L);
            exProcess.start();
        }
    }

 

成员方法

public boolean containsKey(K key) ——判断是否包含key,注意读锁

 

public boolean containsKey(K key){
    	Lock lock = readWriteLock.readLock();
    	lock.lock();
    	try{
	    	return map.containsKey(key);
    	}finally{
    		lock.unlock();
    	}
    }
 

 

public V get(K key) ——从容器里获得key对应的value。根据LRU算法,如果根据key获取元素时,该元素会被认为最近使用,执行先删后加(加在链表尾部表示活跃使用),然后返回key对应的value,注意读写锁

 

public V get(K key){
    	Lock lock = readWriteLock.readLock();
    	lock.lock();
    	try {
			if(map.containsKey(key)){
				Lock writeLock = readWriteLock.writeLock();
				lock.unlock();
				writeLock.lock();				
				try {
					//体现LRU算法:最近使用的元素会被放在最后面位置
					map.put(key,map.remove(key));		// Most-Recent used is always in last
					if(exProcess != null){
					    exProcess.put(key,System.currentTimeMillis());
					}
				}finally {
					lock.lock();
					writeLock.unlock();
				}
				return map.get(key);
			}
			return null;
		} finally {
			lock.unlock();
		}
    }
 

 

public V peek(K key) ——返回key对应的value。peek与get的区别

 

public V peek(K key){
    	Lock lock = readWriteLock.readLock();
    	lock.lock();
    	try {
				return map.get(key);
		} finally {
			lock.unlock();
		}
    }
 

 

public void put(K key, V value) ——如果key已经存在,则先删后加(加在链表尾部),如果容器已满,则先删除第一个元素再add。

 

 public void put(K key, V value){
		if(key == null){
			throw new IllegalArgumentException("Key object cannot be null.");
		}
    	Lock lock = readWriteLock.writeLock();
    	lock.lock();
		try {
			if(map.containsKey(key)){
				map.remove(key);
			}else{
			    if(capacity == 0){
			        return;
			    }
				//体现LRU算法:如果容器满了,则将最老的元素逐出,
				//在这里最老的元素放置在LinkHashMap第一个位置上
				if(map.size()==capacity){	// reach the limit of key list
					K rmKey = map.keySet().iterator().next();	// remove the eldest(LRU) one
					V rmVal = map.remove(rmKey);
			        if(exProcess != null){
			            exProcess.remove(rmKey);
			        }
			        notifyListeners(rmKey,rmVal);
				}
			    if(exProcess != null){
			        exProcess.put(key,System.currentTimeMillis());
			    }
			}
			map.put(key,value);
		} finally {
			lock.unlock();
		}
    }
 

 

public int size() ——容器当前大小

 

public int size(){
    	Lock lock = readWriteLock.readLock();
    	lock.lock();
    	try{
	    	return map.size();
    	}finally{
    		lock.unlock();
    	}
    }
 

 

public int getCapacity() ——获得容器容量

 

public void setCapacity(int newSize) ——设置容器容量,如果新设置的容量大小(newSize)小于容器已经包含的元素数(oldSize),需要将部分元素丢弃掉,从 LinkedHashMap头开始 删除(oldSize-newSize)个元素。

 

 

public void setCapacity(int newSize){
    	Lock lock = readWriteLock.writeLock();
    	lock.lock();
        try {
			this.capacity = newSize;
			if(map.size() > capacity){
				int count = map.size()-capacity;
				//体现LRU算法
				for(Iterator<K> itr = map.keySet().iterator();itr.hasNext()&&(count > 0);count--){  // shrink the map
				    K rmKey = itr.next();   // remove the eldest(LRU) one
				    V rmVal = map.get(rmKey);
				    itr.remove();
				    if(exProcess != null){
				        exProcess.remove(rmKey);
				    }
				    notifyListeners(rmKey,rmVal);
				}
			}
		} finally {
			lock.unlock();
		}
    }
 

 

public V remove(K key) ——将元素从LRUMap容器中及“阎王线程”持有的死亡名单中删除。

 

public V remove(K key) {
    	Lock lock = readWriteLock.writeLock();
    	lock.lock();
        try {
	        if(exProcess != null){
	            exProcess.remove(key);
	        }
	        return map.remove(key);
        }finally{
        	lock.unlock();
        }
    }
 

 

public V evict(K key) ——与remove差别,多了notifyListeners(key,val)

 

public V evict(K key) {
    	Lock lock = readWriteLock.writeLock();
    	lock.lock();
        try {
	        if(exProcess != null){
	            exProcess.remove(key);
	        }
	        V val = map.remove(key);
	        if(val != null){
	        	notifyListeners(key,val);
	        }
	        return val;
        }finally{
        	lock.unlock();
        }
    }
 

 

public List<K> keys() ——获得key的列表

 public List<K> keys(){

    	Lock lock = readWriteLock.readLock();
    	lock.lock();
    	try{
            return new LinkedList<K>(map.keySet());
       	}finally{
    		lock.unlock();
    	}
   }
 

public List<K> getMRUKeys(int num) ——获得排在后面num个元素的key。后面num个元素一般是比较活跃的元素。

 

Listener相关方法:

(注:运用了观察者模式,模式详见参考1,当LRUMap的状态发生变化时,比如调用了evict、setCapacity、put方法时,通知观察者(监听器Listener)做相应处理,具体监听器会实 LRUMapEvictionListener接口

public void addListener(LRUMapEvictionListener<K,V> listener) ——将Listener实例加到listeners queue里

public boolean removeListener(LRUMapEvictionListener<K,V> listener) ——从listeners queue里删除该Listener实例

private void notifyListeners(final K rmKey,final V rmVal) ——在evict、setCapacity、put里调用

private void notifyListeners(final K rmKey,final V rmVal) {
        if(listeners.isEmpty()){
            return;
        }
        poolExecutor.execute(new Runnable() {		
			public void run() {
				doNotifyListeners(rmKey,rmVal);
			}
		
		});
    }
 

private void doNotifyListeners(final K rmKey,final V rmVal) 

private void doNotifyListeners(final K rmKey,final V rmVal) {
        if(listeners.isEmpty()){
            return;
        }
        for (LRUMapEvictionListener<K,V> l : listeners) {
            l.objectEvicted(rmKey,rmVal);
        }
    }
 

 

监听器接口:

public interface LRUMapEvictionListener<K, V> {
    void objectEvicted(K key, V val);
}

构造LRUMap后,通过 addListener注册监听器实例(可以多次注册,监听器实例存放在LRUMap的成员属性 listeners中 )。

void objectEvicted(K key, V val)传入key和value,从方法名看叫做“对象逐出方法”,一般是在调用了LRUMap的一些操作如 evict、setCapacity、put(按照LRU算法这些操作通常涉及到元素的添加和删除以及位置的变化)时,会调用该处理程序,该处理程序针对不同应用场景有不同实现。

如下示例

private LRUMap<String, IndexWriter> writerCache = new LRUMap<String, IndexWriter>(writerCacheSize, expireTime * 60);

//注册监听器
writerCache.addListener(new LRUMapEvictionListener<String, IndexWriter>() {
           //监听器处理程序
           @Override
           public void objectEvicted(String name, IndexWriter writer) {
              if (log.isInfoEnabled()) {
                 log.info("IndexWriter of :" + name + " is evicted,going to evict correspondent IndexReader .");
              }
              readerCache.evict(name);
              numberOfWriterEvicted.incrementAndGet();
              try {
                 writer.close();
              }catch (Exception e) {
                 log.warn("failed to close writer of :"+name, e);
              }
           }
        });
 

线程工厂:

 

 

后记

1.体会读写锁的使用

 

http://nemogu.iteye.com/blog/1409879

2.java.util和java.util.concurrent中集合类

 

3.实现LRUMap时为什么使用观察者模式

LinkedHashMap<K,V> map中的元素被逐出(Evicte)后,如果想对这个被逐出的对象做处理(比如close)或者做一些其他相关操作,使用观察者模式,可以在map中的元素被逐出时,调用观察者类(监听器类)。

参考

1.观察者模式 http://nemogu.iteye.com/admin/blogs/1407857

 

 

 

分享到:
评论

相关推荐

    基于vue的菜谱网站,前端采用vue,后端采用express,数据库采用mysql。.zip-毕设&课设&实训&大作业&竞赛&项目

    项目工程资源经过严格测试运行并且功能上ok,可实现复现复刻,拿到资料包后可实现复现出一样的项目,本人系统开发经验充足(全栈全领域),有任何使用问题欢迎随时与我联系,我会抽时间努力为您解惑,提供帮助 【资源内容】:包含源码+工程文件+说明等。答辩评审平均分达到96分,放心下载使用!可实现复现;设计报告也可借鉴此项目;该资源内项目代码都经过测试运行,功能ok 【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目,也可基于此项目来扩展开发出更多功能 【提供帮助】:有任何使用上的问题欢迎随时与我联系,抽时间努力解答解惑,提供帮助 【附带帮助】:若还需要相关开发工具、学习资料等,我会提供帮助,提供资料,鼓励学习进步 下载后请首先打开说明文件(如有);整理时不同项目所包含资源内容不同;项目工程可实现复现复刻,如果基础还行,也可在此程序基础上进行修改,以实现其它功能。供开源学习/技术交流/学习参考,勿用于商业用途。质量优质,放心下载使用

    数据分析全流程指南:从基础知识到实战项目的Python&R生态应用

    内容概要:本文档提供了关于数据分析全面的知识介绍与实战资源链接。首先,在数据分析的基础教程部分讲述了使用Python以及R两种语言来进行实际的数据分析工作所需具备的各项基本技能。其次,进阶教程涵盖从机器学习到深度学习的概念及其Python具体应用场景。接着,在工具有效利用层面介绍了多种热门库与平台的作用特点。在项目实践中,列举了四个实战案例:Titanic幸存者预测、房价预测、社交媒体情感倾向分析以及市场顾客购买模式研究,每个项目都有详细的技术流程指引。另外列出多个外部网站资源供进一步提升学习。 适用人群:本文主要面向有志于从事数据挖掘工作的学生和技术爱好者,同时也可辅助在职人士自我能力进阶。无论是在学术科研还是实际业务需求环境中都值得研读。 使用场景及目标:学习者将能够获取到系统的理论知识体系,熟悉业界主流软件包的功能优势,掌握具体业务问题解决方案路径,提高自身的综合技术素质,从而为个人职业规划增添竞争力。 其他说明:文档里推荐了不少高质量参考资料和实用线上学习社区,能有效补充专业知识空白并促进社交协作交流。

    从埃安泰国工厂竣工看中国车企加快海外建厂步伐.pptx

    从埃安泰国工厂竣工看中国车企加快海外建厂步伐.pptx

    复现改进的L-SHADE差分进化算法求解最优化问题详解:附MATLAB源码与测试函数集,复现改进的L-SHADE差分进化算法求解最优化问题详解:MATLAB源码与测试集全攻略,复现改进的L-SHADE

    复现改进的L-SHADE差分进化算法求解最优化问题详解:附MATLAB源码与测试函数集,复现改进的L-SHADE差分进化算法求解最优化问题详解:MATLAB源码与测试集全攻略,复现改进的L-SHADE差分进化算法求最优化问题 对配套文献所提出的改进的L-SHADE差分进化算法求解最优化问题的的复现,提供完整MATLAB源代码和测试函数集,到手可运行,运行效果如图2所示。 代码所用测试函数集与文献相同:对CEC2014最优化测试函数集中的全部30个函数进行了测试验证,运行结果与文献一致。 ,复现; 改进的L-SHADE差分进化算法; 最优化问题求解; MATLAB源代码; 测试函数集; CEC2014最优化测试函数集,复现改进L-SHADE算法:最优化问题的MATLAB求解与验证

    DCDC 电阻分压计算器

    可选择参考电压与输出电压 可选择电阻精度以及输出电压误差值

    西门子博途三部十层电梯程序案例解析:基于Wincc RT Professional V14及更高版本的应用探索,西门子博途三部十层电梯程序案例解析:基于Wincc RT Professional画面与

    西门子博途三部十层电梯程序案例解析:基于Wincc RT Professional V14及更高版本的应用探索,西门子博途三部十层电梯程序案例解析:基于Wincc RT Professional画面与V14及以上版本技术参考,西门子1200博途三部十层电梯程序案例,加Wincc RT Professional画面三部十层电梯程序,版本V14及以上。 程序仅限于参考资料使用。 ,西门子;1200博途;三部十层电梯程序案例;Wincc RT Professional;V14以上程序版本。,西门子V14+博途三部十层电梯程序案例:Wincc RT Pro专业画面技术解析

    2023政务大数据解决方案.pptx

    2023政务大数据解决方案.pptx

    基于SSM设计的校园二手物品交易网站

    项目工程资源经过严格测试运行并且功能上ok,可实现复现复刻,拿到资料包后可实现复现出一样的项目,本人系统开发经验充足(全栈全领域),有任何使用问题欢迎随时与我联系,我会抽时间努力为您解惑,提供帮助 【资源内容】:包含源码+工程文件+说明等。答辩评审平均分达到96分,放心下载使用!可实现复现;设计报告也可借鉴此项目;该资源内项目代码都经过测试运行;功能ok 【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目,也可基于此项目来扩展开发出更多功能 【提供帮助】:有任何使用上的问题欢迎随时与我联系,抽时间努力解答解惑,提供帮助 【附带帮助】:若还需要相关开发工具、学习资料等,我会提供帮助,提供资料,鼓励学习进步 下载后请首先打开说明文件(如有);整理时不同项目所包含资源内容不同;项目工程可实现复现复刻,如果基础还行,也可在此程序基础上进行修改,以实现其它功能。供开源学习/技术交流/学习参考,勿用于商业用途。质量优质,放心下载使用

    基于java的学业跟踪评价系统设计的详细项目实例(含完整的程序,GUI设计和代码详解)

    内容概要:本文介绍了基于Java的学业跟踪评价系统的详细设计与实现,涵盖系统的多维度数据整合与评价、智能化学习建议、数据可视化和实时反馈等方面。系统通过收集课堂表现、作业成绩、考试成绩等多源数据,对学生的学业表现进行全面跟踪和评价,提供可视化反馈以及个性化的学习建议,促进家校互动,助力学生全面素质提升和发展。 适合人群:具备一定Java编程经验的研究者和开发者,特别是从事教育信息化领域的从业人员和技术爱好者。 使用场景及目标:该系统主要用于K12教育阶段、高等教育以及其他涉及教育培训的场景。其目的是提高教育管理效率、推进教育数字化转型和个人化教育实施。 其他说明:该文档详细介绍了系统的设计思路、功能模块和技术细节,并提供了完整的程序代码以及GUI设计说明。对于希望深入了解或实际部署学业跟踪评价系统的机构非常有参考价值。文中强调技术创新与实践经验相结合,突出了实用性和前瞻性特点。

    基于vue实现的WebAPP.zip

    项目工程资源经过严格测试运行并且功能上ok,可实现复现复刻,拿到资料包后可实现复现出一样的项目,本人系统开发经验充足(全栈全领域),有任何使用问题欢迎随时与我联系,我会抽时间努力为您解惑,提供帮助 【资源内容】:包含源码+工程文件+说明等。答辩评审平均分达到96分,放心下载使用!可实现复现;设计报告也可借鉴此项目;该资源内项目代码都经过测试运行;功能ok 【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目,也可基于此项目来扩展开发出更多功能 【提供帮助】:有任何使用上的问题欢迎随时与我联系,抽时间努力解答解惑,提供帮助 【附带帮助】:若还需要相关开发工具、学习资料等,我会提供帮助,提供资料,鼓励学习进步 下载后请首先打开说明文件(如有);整理时不同项目所包含资源内容不同;项目工程可实现复现复刻,如果基础还行,也可在此程序基础上进行修改,以实现其它功能。供开源学习/技术交流/学习参考,勿用于商业用途。质量优质,放心下载使用

    rabbmit相关安装包

    erlang安装包,rabbmit安装环境

    linux 下的oracle数据库的开机启动脚本

    linux 下的oracle数据库的开机启动脚本,将里面的/home/oracle/app/oracle/product/11.2.0/dbhome_1 都改成你的oracle数据库的路径。在root用户下chmod +x 添加执行权限,然后./oracle_setup.sh 执行即可。

    基于目标级联分析法的多微网主动配电系统自治优化经济调度算法实现与初级应用,基于目标级联分析法的多微网主动配电系统自治优化经济调度算法实践:初级拉格朗日算法应用,GAMS代码:基于目标级联分析法的多微网

    基于目标级联分析法的多微网主动配电系统自治优化经济调度算法实现与初级应用,基于目标级联分析法的多微网主动配电系统自治优化经济调度算法实践:初级拉格朗日算法应用,GAMS代码:基于目标级联分析法的多微网主动配电系统自治优化经济调度 该代码并非完全复现该文献,而是参照文献 《基于目标级联分析法的多微网主动配电系统自治优化经济调度》 的目标级联分析法(ATC)的算法部分,采用初级的拉格朗日算法,主网与配网部分模型较为简化。 代码结构完整,注释详细,可读性较强,可以在此基础上进行修改或者移植。 适用于初学者学习ATC模型 ,GAMS代码;目标级联分析法(ATC);微网主动配电系统;自治优化经济调度;拉格朗日算法;主网与配网模型简化;代码结构完整;注释详细;可读性强;初学者学习ATC模型。,基于ATC算法的GAMS多微网经济调度优化代码:简化版学习指南

    基于ISODATA改进算法的负荷场景曲线聚类-适用于风光场景生成的高效算法创新,基于ISODATA改进算法的负荷场景曲线聚类(适用于风光场景生成,包含K-means等多种聚类方法与效果评价),基于I

    基于ISODATA改进算法的负荷场景曲线聚类——适用于风光场景生成的高效算法创新,基于ISODATA改进算法的负荷场景曲线聚类(适用于风光场景生成,包含K-means等多种聚类方法与效果评价),基于ISODATA改进算法的负荷场景曲线聚类(适用于风光场景生成) 摘要:代码主要做的是一种基于改进ISODATA算法的负荷场景曲线聚类,代码中,主要做了四种聚类算法,包括基础的K-means算法、ISODATA算法、L-ISODATA算法以及K-L-ISODATA算法,并且包含了对聚类场景以及聚类效果的评价,通过DBI的计算值综合对比评价不同方法的聚类效果,程序实现效果非常好,适合对于算法创新有需求的人,且也包含基础的k-means算法,用来学习也非常棒 另外,此代码同样适用于风光场景生成,自己准备好风光场景数据即可 代码非常精品,有部分注释; ,核心关键词: 1. 基于ISODATA改进算法 2. 负荷场景曲线聚类 3. K-means算法 4. 聚类场景评价 5. 聚类效果评价 6. DBI计算值 7. 算法创新需求 8. 风光场景生成 以上关键词用分号分隔为: 1. 基于ISO

    xpack-qemu-arm-8.2.2-1-win32-x64.zip

    xPack qemu arm 是一款高性能且跨平台的 ARM 架构虚拟机

    莫理莉+AI+为新型能源系统赋能-技术与建筑建筑供配电论坛琶洲.pptx

    莫理莉+AI+为新型能源系统赋能-技术与建筑建筑供配电论坛琶洲.pptx

    学生毕业离校系统(源码+数据库+论文+ppt)java开发springboot框架javaweb,可做计算机毕业设计或课程设计

    学生毕业离校系统(源码+数据库+论文+ppt)java开发springboot框架javaweb,可做计算机毕业设计或课程设计 【功能需求】 本系统分为学生、教师、管理员3个角色 (1)学生功能需求 学生进入系统可以查看首页、个人中心、离校流程、网站公告、费用结算管理、论文审核管理、我的收藏管理等操作。 (2)教师功能需求 教师进入系统可以查看首页、学生管理、离校流程管理、费用结算管理、论文审核管理等操作。 (2)管理员功能需求 管理员登陆后,主要功能模块包括首页、个人中心、学生管理、教师管理、离校信息管理、费用结算管理、论文审核管理、管理员管理、留言板管理、系统管理等功能。 【环境需要】 1.运行环境:最好是java jdk 1.8,我们在这个平台上运行的。其他版本理论上也可以。 2.IDE环境:IDEA,Eclipse,Myeclipse都可以。 3.tomcat环境:Tomcat 7.x,8.x,9.x版本均可 4.数据库:MySql 5.7/8.0等版本均可; 【购买须知】 本源码项目经过严格的调试,项目已确保无误,可直接用于课程实训或毕业设计提交。里面都有配套的运行环境软件,讲解视频,部署视频教程,一应俱全,可以自己按照教程导入运行。附有论文参考,使学习者能够快速掌握系统设计和实现的核心技术。

    揭秘 OpenAI 在 2027 年前创建 AGI 的计划.pptx

    揭秘 OpenAI 在 2027 年前创建 AGI 的计划.pptx

    单极双极调制下,线路阻抗不匹配时两台单相逆变器并联的离散仿真模型研究,单极双极调制下,线路阻抗不匹配时单相逆变器Simulink并联仿真模型研究,单相逆变器Simulink并联离散仿真模型,输入电压4

    单极双极调制下,线路阻抗不匹配时两台单相逆变器并联的离散仿真模型研究,单极双极调制下,线路阻抗不匹配时单相逆变器Simulink并联仿真模型研究,单相逆变器Simulink并联离散仿真模型,输入电压400V,单台逆变器功率为2000W,使用下垂控制方案,在线路阻抗不匹配的情况下,实现两台逆变器并联。 可以选调制方案为单极性调制或者双极性调制。 离散模型,功率均分效果,两台逆变器输出电压和电流波形如下图。 ,核心关键词:单相逆变器; Simulink; 并联离散仿真模型; 输入电压400V; 单台功率2000W; 下垂控制方案; 线路阻抗不匹配; 调制方案; 单极性调制; 双极性调制; 功率均分效果。,离散仿真模型下,单相逆变器并联研究——400V输入、2000W功率均分实现

Global site tag (gtag.js) - Google Analytics