- 浏览: 990296 次
-
文章分类
- 全部博客 (428)
- Hadoop (2)
- HBase (1)
- ELK (1)
- ActiveMQ (13)
- Kafka (5)
- Redis (14)
- Dubbo (1)
- Memcached (5)
- Netty (56)
- Mina (34)
- NIO (51)
- JUC (53)
- Spring (13)
- Mybatis (17)
- MySQL (21)
- JDBC (12)
- C3P0 (5)
- Tomcat (13)
- SLF4J-log4j (9)
- P6Spy (4)
- Quartz (12)
- Zabbix (7)
- JAVA (9)
- Linux (15)
- HTML (9)
- Lucene (0)
- JS (2)
- WebService (1)
- Maven (4)
- Oracle&MSSQL (14)
- iText (11)
- Development Tools (8)
- UTILS (4)
- LIFE (8)
最新评论
-
Donald_Draper:
Donald_Draper 写道刘落落cici 写道能给我发一 ...
DatagramChannelImpl 解析三(多播) -
Donald_Draper:
刘落落cici 写道能给我发一份这个类的源码吗Datagram ...
DatagramChannelImpl 解析三(多播) -
lyfyouyun:
请问楼主,执行消息发送的时候,报错:Transport sch ...
ActiveMQ连接工厂、连接详解 -
ezlhq:
关于 PollArrayWrapper 状态含义猜测:参考 S ...
WindowsSelectorImpl解析一(FdMap,PollArrayWrapper) -
flyfeifei66:
打算使用xmemcache作为memcache的客户端,由于x ...
Memcached分布式客户端(Xmemcached)
Channel接口定义:http://donald-draper.iteye.com/blog/2369111
AbstractInterruptibleChannel接口定义:http://donald-draper.iteye.com/blog/2369238
SelectableChannel接口定义:http://donald-draper.iteye.com/blog/2369317
SelectionKey定义:http://donald-draper.iteye.com/blog/2369499
SelectorProvider定义:http://donald-draper.iteye.com/blog/2369615
AbstractSelectableChannel定义:http://donald-draper.iteye.com/blog/2369742
NetworkChannel接口定义:http://donald-draper.iteye.com/blog/2369773
ServerSocketChannel定义:http://donald-draper.iteye.com/blog/2369836
Selector定义:http://donald-draper.iteye.com/blog/2370015
AbstractSelector定义:http://donald-draper.iteye.com/blog/2370138
上一篇我们看了一下AbstractSelector,主要是维护取消key集合,和key的反注册。
取消的key放在一个set集合中,对集合进行添加操作时,必须同步取消key set集合。
反注册选择key完成的实际工作是,将key,从key对应的通道的选择key数组(这个我们在选择通道相关文章中有讲)中移除。
今天来看一下SelectorImpl
再来看构造的在bugLevel为1.4的情况下,就绪key和key集合的代理集合初始化分2步看:
1.BugLevel为1.4
2.BugLevel不为1.4
//Util,nio通道工具类,从定义来看应该是缓冲区工具
//通道IO工具
上面两个工具类我们在以后遇到的时候再讲,粗略地看一了,Util为nio的缓冲区工具,IOUtil为通道IO工具。
再回到就绪key和key集合的代理集合初始化的第一点:
//Util
关于bugLevel的相关连接:
Sun GlassFish Enterprise Server v3 Release Notes:
https://docs.oracle.com/cd/E19226-01/820-7688/6niu9p8i3/index.html
Use of the bug level variable -Dsun.nio.ch.bugLevel=1.4:
https://community.oracle.com/thread/1240510
从上面来看bugLevel对应的是虚拟机启动的参数配置sun.nio.ch.bugLevel,
由于在nio包在1.4时加入,包中有一个bug问题,
这个bug在jdk1.5中存在,直到jdk1.7才修复。
从上面的这些信息来看bugLevel应该是标记nio存在bug情况的jdk版本,
如果有不同的理解,可以给我留言。
atBugLevel方法有两点关注:
a.判断虚拟机是否启动
b.获取虚拟机参数sun.nio.ch.bugLevel
先看第一点
a.判断虚拟机是否启动
b.获取虚拟机参数sun.nio.ch.bugLevel
//GetPropertyAction,获取系统属性Action
从上面一段分析可以看出,如果nio包的JDK版本存在bug问题,则就绪key和key集合的代理集合直接引用就绪key和key集合。
再回到就绪key和key集合的代理集合初始化的第二点:
2.BugLevel不为1.4
将当前key集合包装成不可修改的集合publicKes,这个就不用说了,我们以前在java的集合综述篇中有说。我们主要将下一点将就绪key集合包装成容量固定的集合,
//Util
从上面来看
Util.ungrowableSet(Set set)方法,对集合Set进行简单的封装,移除迭代,比较等操作
直接委托给原始的Set集合,只是封装后的集合不允许添加元素,但可以移除,查询操作。
这段话是不是很熟悉,在Selector定义的文章,Java Doc有说就绪key集合SelectedKeys的
这些属性。
小节一下就绪key和key集合的初始化:
如果nio包的JDK版本存在bug问题,则就绪key和key集合的代理集合直接引用就绪key和key集合。否则将当前key集合包装成不可修改的代理集合publicKes,将就绪key集合包装成容量固定的集合publicSelectedKeys
再来看获取就绪key和key集合
//key集合
//就绪key
从上面来看,其他线程获取选择器的就绪key和key集合,实际上返回的是
key集合的代理publicKeys和就绪key集合的代理publicSelectedKeys。
再来看几个选择操作:
再来看lockAndDoSelect方法:
在上面的方法中有一些:
这个是什么意思,不是很理解,找了一下资料
JVM INSTR:
https://coderanch.com/t/385088/java/JVM-INSTR
JVM INSTR monitorenter and JVM INSTR monitorexit:
http://stackoverflow.com/questions/9547975/jvm-instr-monitorenter-and-jvm-instr-monitorexit
按照资料的说法,上述的这标记是JVM规范,实际相当与同步语句块(synchronized);
JVM INSTR monitorenter进入同步,JVM INSTR monitorexit退出同步;
相等于
再来看实际选择操作
//实际选择操作
//待父类扩展,我们在下一篇文章中再看
select方法的3中操作形式,实际上委托给为lockAndDoSelect方法,方法实际上是同步的,
可安全访问,获取key集合代理publicKeys和就绪key代理集合publicSelectedKeys,然后交给
doSelect(long l)方法,这个方法为抽象方法,待子类扩展。
在AbstractSelector的close方法,最有调用了implCloseSelector;
下面来看关闭选择器的实际操作implCloseSelector
从implCloseSelector方法来看,首先唤醒等待选择操作的线程,唤醒方法wakeup待实现,
同步选择器,就绪key和key集合的代理publicKeys,publicSelectedKeys,调用implClose完成实际的关闭通道工作,待子类实现。
再来看注册通道到选择器:
从可选通道注册方法来看,首先注册的通道必须是AbstractSelectableChannel类型,并且是SelChImpl实例。更具可选择通道和选择器构造选择key,设置选择key的附加物,同步key集合代理,调用implRegister方法完成实际的注册工作,implRegister方法待子类实现。
//再来看处理反注册队列,现在看,还不能完全理解此方法的意思,在后面的文章,
我们会继续说,现在不能能完全看到,只以目前的能力,阅读以下代码,理解多少是多少,
因为里面牵涉到JVM规范,不知道说的正不正确,我只以目前的能力来阅读代码。
从processDeregisterQueue方法来看,主要是遍历取消key集合,反注册取消key,实际的
反注册工作由implDereg方法,implDereg方法待子类扩展。
成功,则从集合中移除。
这个方法,待子类实现,我们以后再看
总结:
SelectorImpl有4个集合分别为就绪key集合,key集合,key集合的代理publicKeys及就绪key集合的代理publicSelectedKeys;实际是两个集合就绪key集合和key集合,publicSelectedKeys和publicKeys是其他线程访问上述两个集合的代理。
SelectorImpl构造的时候,初始化选择器提供者SelectorProvider,创建就绪key集合和key集合,然后初始化就绪key和key集合的代理,初始化过程为,如果nio包的JDK版本存在bug问题,则就绪key和key集合的代理集合直接引用就绪key和key集合。否则将当前key集合包装成不可修改的代理集合publicKes,将就绪key集合包装成容量固定的集合publicSelectedKeys。
其他线程获取选择器的就绪key和key集合,实际上返回的是key集合的代理publicKeys和就绪key集合的代理publicSelectedKeys。
select方法的3中操作形式,实际上委托给为lockAndDoSelect方法,方法实际上是同步的,可安全访问,获取key集合代理publicKeys和就绪key代理集合publicSelectedKeys,然后交给doSelect(long l)方法,这个方法为抽象方法,待子类扩展。实际的关闭选择器操作implCloseSelector方法,首先唤醒等待选择操作的线程,唤醒方法wakeup待实现,同步选择器,就绪key和key集合的代理publicKeys,publicSelectedKeys,调用implClose完成实际的关闭通道工作,待子类实现。
可选通道注册方法,首先注册的通道必须是AbstractSelectableChannel类型,并且是SelChImpl实例。更具可选择通道和选择器构造选择key,设置选择key的附加物,同步key集合代理,调用implRegister方法完成实际的注册工作,implRegister方法待子类实现。
processDeregisterQueue方法,主要是遍历取消key集合,反注册取消key,实际的反注册工作由implDereg方法,implDereg方法待子类扩展。成功,则从集合中移除。
附:这部分只作为扩展,没有特别的解析,设计,只是贴出代码,有兴趣可以看一下
//VM
在代码中经常看到这个语句JVM INSTR monitorenter ;来看一下JVM:
只贴出源码,暂时放在这以后再啃。
来看这一句:
jsdt:JavaScript Development Tools (JSDT):
http://www.eclipse.org/webtools/jsdt/
//LoadLibraryAction
//System
//Runtime
//ClassLoader
AbstractInterruptibleChannel接口定义:http://donald-draper.iteye.com/blog/2369238
SelectableChannel接口定义:http://donald-draper.iteye.com/blog/2369317
SelectionKey定义:http://donald-draper.iteye.com/blog/2369499
SelectorProvider定义:http://donald-draper.iteye.com/blog/2369615
AbstractSelectableChannel定义:http://donald-draper.iteye.com/blog/2369742
NetworkChannel接口定义:http://donald-draper.iteye.com/blog/2369773
ServerSocketChannel定义:http://donald-draper.iteye.com/blog/2369836
Selector定义:http://donald-draper.iteye.com/blog/2370015
AbstractSelector定义:http://donald-draper.iteye.com/blog/2370138
上一篇我们看了一下AbstractSelector,主要是维护取消key集合,和key的反注册。
取消的key放在一个set集合中,对集合进行添加操作时,必须同步取消key set集合。
反注册选择key完成的实际工作是,将key,从key对应的通道的选择key数组(这个我们在选择通道相关文章中有讲)中移除。
今天来看一下SelectorImpl
abstract class SelectorImpl extends AbstractSelector { protected Set selectedKeys;//就绪key集合,即已经操作事件准备就绪的选择key protected HashSet keys;//与选择器关联的key集合 private Set publicKeys;//外部访问key集合的代理 private Set publicSelectedKeys;//外部访问就绪key集合代理 protected SelectorImpl(SelectorProvider selectorprovider) { super(selectorprovider); //初始化就绪key集合和key集合 keys = new HashSet(); selectedKeys = new HashSet(); if(Util.atBugLevel("1.4")) { publicKeys = keys; publicSelectedKeys = selectedKeys; } else { //将当前key集合包装成不可修改的集合publicKes publicKeys = Collections.unmodifiableSet(keys); //将就绪key集合包装成容量固定的集合 publicSelectedKeys = Util.ungrowableSet(selectedKeys); } } }
再来看构造的在bugLevel为1.4的情况下,就绪key和key集合的代理集合初始化分2步看:
1.BugLevel为1.4
if(Util.atBugLevel("1.4")) { publicKeys = keys; publicSelectedKeys = selectedKeys; }
2.BugLevel不为1.4
else { //将当前key集合包装成不可修改的集合publicKes publicKeys = Collections.unmodifiableSet(keys); //将就绪key集合包装成容量固定的集合 publicSelectedKeys = Util.ungrowableSet(selectedKeys); }
//Util,nio通道工具类,从定义来看应该是缓冲区工具
class Util { private static ThreadLocal localSelector = new ThreadLocal(); private static ThreadLocal localSelectorWrapper = new ThreadLocal(); private static Unsafe unsafe = Unsafe.getUnsafe(); private static int pageSize = -1; private static volatile Constructor directByteBufferConstructor = null; private static volatile Constructor directByteBufferRConstructor = null; private static volatile String bugLevel = null; private static boolean loaded = false; static final boolean $assertionsDisabled = !sun/nio/ch/Util.desiredAssertionStatus(); static { //通道IO工具 TEMP_BUF_POOL_SIZE = IOUtil.IOV_MAX; } }

//通道IO工具
class IOUtil { ...,这里省略一些方法,用到的时候再讲,主要是读写Socket static native boolean randomBytes(byte abyte0[]); static native long makePipe(boolean flag); static native boolean drain(int i) throws IOException; //配置阻塞模式 static native void configureBlocking(FileDescriptor filedescriptor, boolean flag) throws IOException; //获取文件描述(Socket)的值 static native int fdVal(FileDescriptor filedescriptor); //设置文件描述的值 static native void setfdVal(FileDescriptor filedescriptor, int i); static native int iovMax(); static native void initIDs(); static final int IOV_MAX = iovMax(); static final boolean $assertionsDisabled = !sun/nio/ch/IOUtil.desiredAssertionStatus(); static { Util.load(); } }

上面两个工具类我们在以后遇到的时候再讲,粗略地看一了,Util为nio的缓冲区工具,IOUtil为通道IO工具。
再回到就绪key和key集合的代理集合初始化的第一点:
if(Util.atBugLevel("1.4")) { publicKeys = keys; publicSelectedKeys = selectedKeys; }
//Util
static boolean atBugLevel(String s) { if(bugLevel == null) { if(!VM.isBooted()) //如果虚拟器没启动,则返回false return false; //在当前线程访问控制权限的环境下,获取系统属性sun.nio.ch.bugLevel String s1 = (String)AccessController.doPrivileged(new GetPropertyAction("sun.nio.ch.bugLevel")); bugLevel = s1 == null ? "" : s1; } return bugLevel.equals(s); }
关于bugLevel的相关连接:
Sun GlassFish Enterprise Server v3 Release Notes:
https://docs.oracle.com/cd/E19226-01/820-7688/6niu9p8i3/index.html
Use of the bug level variable -Dsun.nio.ch.bugLevel=1.4:
https://community.oracle.com/thread/1240510
从上面来看bugLevel对应的是虚拟机启动的参数配置sun.nio.ch.bugLevel,
由于在nio包在1.4时加入,包中有一个bug问题,
"java.lang.NullPointerException at sun.nio.ch.Util.atBugLevel(Util.java:326) at sun.nio.ch.SelectorImpl.<init>(SelectorImpl.java:40) at sun.nio.ch.WindowsSelectorImpl.<init>(WindowsSelectorImpl.java:104) at sun.nio.ch.WindowsSelectorProvider.openSelector(WindowsSelectorProvider.java:26) at java.nio.channels.Selector.open(Selector.java:209)
这个bug在jdk1.5中存在,直到jdk1.7才修复。
从上面的这些信息来看bugLevel应该是标记nio存在bug情况的jdk版本,
如果有不同的理解,可以给我留言。
atBugLevel方法有两点关注:
a.判断虚拟机是否启动
b.获取虚拟机参数sun.nio.ch.bugLevel
先看第一点
a.判断虚拟机是否启动
package sun.misc; import java.util.Properties; // Referenced classes of package sun.misc: // OSEnvironment, VMNotification public class VM { public VM() { } //下面这些变量,暂时不选关注,以后有时间, //我们在看,只需要看到的虚拟机是否启动booted private static boolean suspended = false; /** * @deprecated Field STATE_GREEN is deprecated */ public static final int STATE_GREEN = 1; /** * @deprecated Field STATE_YELLOW is deprecated */ public static final int STATE_YELLOW = 2; /** * @deprecated Field STATE_RED is deprecated */ public static final int STATE_RED = 3; private static volatile boolean booted = false; private static long directMemory = 67108864L;/64M private static boolean pageAlignDirectMemory; private static boolean defaultAllowArraySyntax; private static boolean allowArraySyntax; private static final Properties savedProps = new Properties(); private static volatile int finalRefCount = 0; private static volatile int peakFinalRefCount = 0; private static final int JVMTI_THREAD_STATE_ALIVE = 1; private static final int JVMTI_THREAD_STATE_TERMINATED = 2; private static final int JVMTI_THREAD_STATE_RUNNABLE = 4; private static final int JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER = 1024; private static final int JVMTI_THREAD_STATE_WAITING_INDEFINITELY = 16; private static final int JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT = 32; static { defaultAllowArraySyntax = false; allowArraySyntax = defaultAllowArraySyntax; initialize(); } private static native void initialize(); public static void booted() { booted = true; } //VM是否启动 public static boolean isBooted() { return booted; } }
b.获取虚拟机参数sun.nio.ch.bugLevel
//GetPropertyAction,获取系统属性Action
package sun.security.action; import java.security.PrivilegedAction; public class GetPropertyAction implements PrivilegedAction { private String theProp; private String defaultVal; public GetPropertyAction(String s) { theProp = s; } public GetPropertyAction(String s, String s1) { theProp = s; defaultVal = s1; } //获取系统属性,为空返回默认属性值 public String run() { String s = System.getProperty(theProp); return s != null ? s : defaultVal; } public volatile Object run() { return run(); } }
从上面一段分析可以看出,如果nio包的JDK版本存在bug问题,则就绪key和key集合的代理集合直接引用就绪key和key集合。
再回到就绪key和key集合的代理集合初始化的第二点:
2.BugLevel不为1.4
else { //将当前key集合包装成不可修改的集合publicKes publicKeys = Collections.unmodifiableSet(keys); //将就绪key集合包装成容量固定的集合 publicSelectedKeys = Util.ungrowableSet(selectedKeys); }
将当前key集合包装成不可修改的集合publicKes,这个就不用说了,我们以前在java的集合综述篇中有说。我们主要将下一点将就绪key集合包装成容量固定的集合,
//Util
static Set ungrowableSet(Set set) { return new Set(set) { final Set val$s; { s = set; super(); } public int size() { return s.size(); } public boolean isEmpty() { return s.isEmpty(); } public boolean contains(Object obj) { return s.contains(obj); } ... public Iterator iterator() { return s.iterator(); } ... public void clear() { s.clear(); } public boolean remove(Object obj) { return s.remove(obj); } public boolean containsAll(Collection collection) { return s.containsAll(collection); } public boolean removeAll(Collection collection) { return s.removeAll(collection); } public boolean retainAll(Collection collection) { return s.retainAll(collection); } //集合不可添加元素 public boolean add(Object obj) { throw new UnsupportedOperationException(); } public boolean addAll(Collection collection) { throw new UnsupportedOperationException(); } }; }
从上面来看
Util.ungrowableSet(Set set)方法,对集合Set进行简单的封装,移除迭代,比较等操作
直接委托给原始的Set集合,只是封装后的集合不允许添加元素,但可以移除,查询操作。
这段话是不是很熟悉,在Selector定义的文章,Java Doc有说就绪key集合SelectedKeys的
这些属性。
小节一下就绪key和key集合的初始化:
如果nio包的JDK版本存在bug问题,则就绪key和key集合的代理集合直接引用就绪key和key集合。否则将当前key集合包装成不可修改的代理集合publicKes,将就绪key集合包装成容量固定的集合publicSelectedKeys
再来看获取就绪key和key集合
//key集合
public Set keys() { if(!isOpen() && !Util.atBugLevel("1.4")) throw new ClosedSelectorException(); else return publicKeys; }
//就绪key
public Set selectedKeys() { if(!isOpen() && !Util.atBugLevel("1.4")) throw new ClosedSelectorException(); else return publicSelectedKeys; }
从上面来看,其他线程获取选择器的就绪key和key集合,实际上返回的是
key集合的代理publicKeys和就绪key集合的代理publicSelectedKeys。
再来看几个选择操作:
public int select() throws IOException { //委托给select(long l) return select(0L); } public int select(long l) throws IOException { if(l < 0L) //负数抛出异常 throw new IllegalArgumentException("Negative timeout"); else //委托给lockAndDoSelect(long l) return lockAndDoSelect(l != 0L ? l : -1L); } public int selectNow() throws IOException { //委托给lockAndDoSelect(long l) return lockAndDoSelect(0L); }
再来看lockAndDoSelect方法:
private int lockAndDoSelect(long l) throws IOException { SelectorImpl selectorimpl = this; JVM INSTR monitorenter ; if(!isOpen()) throw new ClosedSelectorException(); //取得key集合代理 Set set = publicKeys; JVM INSTR monitorenter ; //取得就绪key代理 Set set1 = publicSelectedKeys; JVM INSTR monitorenter ; //实际选择操作代理 return doSelect(l); Exception exception; exception; throw exception; Exception exception1; exception1; throw exception1; Exception exception2; exception2; throw exception2; }
在上面的方法中有一些:
JVM INSTR monitorenter ; ... Exception exception; exception; throw exception;
这个是什么意思,不是很理解,找了一下资料
JVM INSTR:
https://coderanch.com/t/385088/java/JVM-INSTR
JVM INSTR monitorenter and JVM INSTR monitorexit:
http://stackoverflow.com/questions/9547975/jvm-instr-monitorenter-and-jvm-instr-monitorexit
按照资料的说法,上述的这标记是JVM规范,实际相当与同步语句块(synchronized);
JVM INSTR monitorenter进入同步,JVM INSTR monitorexit退出同步;
Exception exception; exception; throw exception;
相等于
catch(Exception exception) { throw exception; }
再来看实际选择操作
//实际选择操作
return doSelect(l);
//待父类扩展,我们在下一篇文章中再看
protected abstract int doSelect(long l) throws IOException;
select方法的3中操作形式,实际上委托给为lockAndDoSelect方法,方法实际上是同步的,
可安全访问,获取key集合代理publicKeys和就绪key代理集合publicSelectedKeys,然后交给
doSelect(long l)方法,这个方法为抽象方法,待子类扩展。
在AbstractSelector的close方法,最有调用了implCloseSelector;
下面来看关闭选择器的实际操作implCloseSelector
public void implCloseSelector() throws IOException { wakeup(); synchronized(this) { synchronized(publicKeys) { synchronized(publicSelectedKeys) { implClose(); } } } }
//唤醒等待选择操作的线程,待子类扩展 public abstract Selector wakeup();
//完成实际的关闭选择器工作 protected abstract void implClose() throws IOException;
从implCloseSelector方法来看,首先唤醒等待选择操作的线程,唤醒方法wakeup待实现,
同步选择器,就绪key和key集合的代理publicKeys,publicSelectedKeys,调用implClose完成实际的关闭通道工作,待子类实现。
再来看注册通道到选择器:
protected final SelectionKey register(AbstractSelectableChannel abstractselectablechannel, int i, Object obj) { if(!(abstractselectablechannel instanceof SelChImpl)) //如果可选择通道不是SelChImpl的实例,则抛出IllegalSelectorException throw new IllegalSelectorException(); //更具可选择通道和选择器创建选择key SelectionKeyImpl selectionkeyimpl = new SelectionKeyImpl((SelChImpl)abstractselectablechannel, this); //设置key的附加物 selectionkeyimpl.attach(obj); //同步key集合代理 synchronized(publicKeys) { //完成实际的注册工作 implRegister(selectionkeyimpl); } //设置key的兴趣事件集 selectionkeyimpl.interestOps(i); return selectionkeyimpl; }
//待子类实现 protected abstract void implRegister(SelectionKeyImpl selectionkeyimpl);
从可选通道注册方法来看,首先注册的通道必须是AbstractSelectableChannel类型,并且是SelChImpl实例。更具可选择通道和选择器构造选择key,设置选择key的附加物,同步key集合代理,调用implRegister方法完成实际的注册工作,implRegister方法待子类实现。
//再来看处理反注册队列,现在看,还不能完全理解此方法的意思,在后面的文章,
我们会继续说,现在不能能完全看到,只以目前的能力,阅读以下代码,理解多少是多少,
因为里面牵涉到JVM规范,不知道说的正不正确,我只以目前的能力来阅读代码。
void processDeregisterQueue() throws IOException { Set set = cancelledKeys();//获取取消key集合 Set set1 = set; JVM INSTR monitorenter ;//进入同步语句块 Iterator iterator; if(set.isEmpty()) break MISSING_BLOCK_LABEL_110; iterator = set.iterator(); _L2://遍历取消key集合 SelectionKeyImpl selectionkeyimpl; if(!iterator.hasNext()) break; /* Loop/switch isn't completed */ selectionkeyimpl = (SelectionKeyImpl)iterator.next(); try { //完成实际取消选择key的反注册 implDereg(selectionkeyimpl); } catch(SocketException socketexception) { IOException ioexception = new IOException("Error deregistering key"); ioexception.initCause(socketexception); throw ioexception; } //从取消key集合中移除已经反注册的取消选择key iterator.remove(); if(true) goto _L2; else goto _L1 _L1: break MISSING_BLOCK_LABEL_110; Exception exception; exception; iterator.remove(); throw exception; Exception exception1; exception1; throw exception1; }
//完成SelectionKey的实际反注册工作 protected abstract void implDereg(SelectionKeyImpl selectionkeyimpl) throws IOException;
从processDeregisterQueue方法来看,主要是遍历取消key集合,反注册取消key,实际的
反注册工作由implDereg方法,implDereg方法待子类扩展。
成功,则从集合中移除。
这个方法,待子类实现,我们以后再看
void putEventOps(SelectionKeyImpl selectionkeyimpl, int i) { }
总结:
SelectorImpl有4个集合分别为就绪key集合,key集合,key集合的代理publicKeys及就绪key集合的代理publicSelectedKeys;实际是两个集合就绪key集合和key集合,publicSelectedKeys和publicKeys是其他线程访问上述两个集合的代理。
SelectorImpl构造的时候,初始化选择器提供者SelectorProvider,创建就绪key集合和key集合,然后初始化就绪key和key集合的代理,初始化过程为,如果nio包的JDK版本存在bug问题,则就绪key和key集合的代理集合直接引用就绪key和key集合。否则将当前key集合包装成不可修改的代理集合publicKes,将就绪key集合包装成容量固定的集合publicSelectedKeys。
其他线程获取选择器的就绪key和key集合,实际上返回的是key集合的代理publicKeys和就绪key集合的代理publicSelectedKeys。
select方法的3中操作形式,实际上委托给为lockAndDoSelect方法,方法实际上是同步的,可安全访问,获取key集合代理publicKeys和就绪key代理集合publicSelectedKeys,然后交给doSelect(long l)方法,这个方法为抽象方法,待子类扩展。实际的关闭选择器操作implCloseSelector方法,首先唤醒等待选择操作的线程,唤醒方法wakeup待实现,同步选择器,就绪key和key集合的代理publicKeys,publicSelectedKeys,调用implClose完成实际的关闭通道工作,待子类实现。
可选通道注册方法,首先注册的通道必须是AbstractSelectableChannel类型,并且是SelChImpl实例。更具可选择通道和选择器构造选择key,设置选择key的附加物,同步key集合代理,调用implRegister方法完成实际的注册工作,implRegister方法待子类实现。
processDeregisterQueue方法,主要是遍历取消key集合,反注册取消key,实际的反注册工作由implDereg方法,implDereg方法待子类扩展。成功,则从集合中移除。
附:这部分只作为扩展,没有特别的解析,设计,只是贴出代码,有兴趣可以看一下
//VM
package sun.misc; import java.util.Properties; // Referenced classes of package sun.misc: // OSEnvironment, VMNotification public class VM { private static boolean suspended = false; /** * @deprecated Field STATE_GREEN is deprecated */ public static final int STATE_GREEN = 1; /** * @deprecated Field STATE_YELLOW is deprecated */ public static final int STATE_YELLOW = 2; /** * @deprecated Field STATE_RED is deprecated */ public static final int STATE_RED = 3; private static volatile boolean booted = false; private static long directMemory = 67108864L; private static boolean pageAlignDirectMemory; private static boolean defaultAllowArraySyntax; private static boolean allowArraySyntax; private static final Properties savedProps = new Properties(); private static volatile int finalRefCount = 0; private static volatile int peakFinalRefCount = 0; private static final int JVMTI_THREAD_STATE_ALIVE = 1; private static final int JVMTI_THREAD_STATE_TERMINATED = 2; private static final int JVMTI_THREAD_STATE_RUNNABLE = 4; private static final int JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER = 1024; private static final int JVMTI_THREAD_STATE_WAITING_INDEFINITELY = 16; private static final int JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT = 32; static { defaultAllowArraySyntax = false; allowArraySyntax = defaultAllowArraySyntax; initialize(); } public VM() { } private static native void initialize(); public static void booted() { booted = true; } public static boolean isBooted() { return booted; } public static long maxDirectMemory() { return directMemory; } public static boolean isDirectMemoryPageAligned() { return pageAlignDirectMemory; } public static void initializeOSEnvironment() { if(!booted) OSEnvironment.initialize(); } public static int getFinalRefCount() { return finalRefCount; } public static int getPeakFinalRefCount() { return peakFinalRefCount; } public static void addFinalRefCount(int i) { finalRefCount += i; if(finalRefCount > peakFinalRefCount) peakFinalRefCount = finalRefCount; } public static Thread.State toThreadState(int i) { if((i & 4) != 0) return Thread.State.RUNNABLE; if((i & 1024) != 0) return Thread.State.BLOCKED; if((i & 16) != 0) return Thread.State.WAITING; if((i & 32) != 0) return Thread.State.TIMED_WAITING; if((i & 2) != 0) return Thread.State.TERMINATED; if((i & 1) == 0) return Thread.State.NEW; else return Thread.State.RUNNABLE; } public static boolean allowArraySyntax() { return allowArraySyntax; } /** * @deprecated Method threadsSuspended is deprecated */ public static boolean threadsSuspended() { return suspended; } public static boolean allowThreadSuspension(ThreadGroup threadgroup, boolean flag) { return threadgroup.allowThreadSuspension(flag); } /** * @deprecated Method suspendThreads is deprecated */ public static boolean suspendThreads() { suspended = true; return true; } /** * @deprecated Method unsuspendThreads is deprecated */ public static void unsuspendThreads() { suspended = false; } /** * @deprecated Method unsuspendSomeThreads is deprecated */ public static void unsuspendSomeThreads() { } /** * @deprecated Method getState is deprecated */ public static final int getState() { return 1; } /** * @deprecated Method registerVMNotification is deprecated */ public static void registerVMNotification(VMNotification vmnotification) { /** * @deprecated Method asChange is deprecated */ public static void asChange(int i, int j) { } /** * @deprecated Method asChange_otherthread is deprecated */ public static void asChange_otherthread(int i, int j) { } public static String getSavedProperty(String s) { if(savedProps.isEmpty()) throw new IllegalStateException("Should be non-empty if initialized"); else return savedProps.getProperty(s); } public static void saveAndRemoveProperties(Properties properties) { if(booted) throw new IllegalStateException("System initialization has completed"); savedProps.putAll(properties); String s = (String)properties.remove("sun.nio.MaxDirectMemorySize"); if(s != null) if(s.equals("-1")) { directMemory = Runtime.getRuntime().maxMemory(); } else { long l = Long.parseLong(s); if(l > -1L) directMemory = l; } s = (String)properties.remove("sun.nio.PageAlignDirectMemory"); if("true".equals(s)) pageAlignDirectMemory = true; s = properties.getProperty("sun.lang.ClassLoader.allowArraySyntax"); allowArraySyntax = s != null ? Boolean.parseBoolean(s) : defaultAllowArraySyntax; properties.remove("java.lang.Integer.IntegerCache.high"); properties.remove("sun.zip.disableMemoryMapping"); properties.remove("sun.java.launcher.diag"); } }

在代码中经常看到这个语句JVM INSTR monitorenter ;来看一下JVM:
只贴出源码,暂时放在这以后再啃。
class JVM { JVM() { } static long activate(String s, DTraceProvider adtraceprovider[]) { return activate0(s, adtraceprovider); } static void dispose(long l) { dispose0(l); } static boolean isEnabled(Method method) { return isEnabled0(method); } static boolean isSupported() { return isSupported0(); } static Class defineClass(ClassLoader classloader, String s, byte abyte0[], int i, int j) { return defineClass0(classloader, s, abyte0, i, j); } private static native long activate0(String s, DTraceProvider adtraceprovider[]); private static native void dispose0(long l); private static native boolean isEnabled0(Method method); private static native boolean isSupported0(); private static native Class defineClass0(ClassLoader classloader, String s, byte abyte0[], int i, int j); static { AccessController.doPrivileged(new LoadLibraryAction("jsdt")); } }
来看这一句:
static { AccessController.doPrivileged(new LoadLibraryAction("jsdt")); }
jsdt:JavaScript Development Tools (JSDT):
http://www.eclipse.org/webtools/jsdt/
//LoadLibraryAction
package sun.security.action; import java.security.PrivilegedAction; public class LoadLibraryAction implements PrivilegedAction { public LoadLibraryAction(String s) { theLib = s; } public Void run() { //系统加载lib库 System.loadLibrary(theLib); return null; } public volatile Object run() { return run(); } private String theLib; }
//System
/** * Loads the system library specified by the <code>libname</code> * argument. The manner in which a library name is mapped to the * actual system library is system dependent. * <p> * The call <code>System.loadLibrary(name)</code> is effectively * equivalent to the call * <blockquote><pre> * Runtime.getRuntime().loadLibrary(name) * </pre></blockquote> * * @param libname the name of the library. * @exception SecurityException if a security manager exists and its * <code>checkLink</code> method doesn't allow * loading of the specified dynamic library * @exception UnsatisfiedLinkError if the library does not exist. * @exception NullPointerException if <code>libname</code> is * <code>null</code> * @see java.lang.Runtime#loadLibrary(java.lang.String) * @see java.lang.SecurityManager#checkLink(java.lang.String) */ public static void loadLibrary(String libname) { Runtime.getRuntime().loadLibrary0(getCallerClass(), libname); }


//Runtime
synchronized void loadLibrary0(Class fromClass, String libname) { SecurityManager security = System.getSecurityManager(); if (security != null) { security.checkLink(libname); } if (libname.indexOf((int)File.separatorChar) != -1) { throw new UnsatisfiedLinkError( "Directory separator should not appear in library name: " + libname); } ClassLoader.loadLibrary(fromClass, libname, false); }

//ClassLoader
// Invoked in the java.lang.Runtime class to implement load and loadLibrary. static void loadLibrary(Class fromClass, String name, boolean isAbsolute) { ClassLoader loader = (fromClass == null) ? null : fromClass.getClassLoader(); if (sys_paths == null) { usr_paths = initializePath("java.library.path"); sys_paths = initializePath("sun.boot.library.path"); } if (isAbsolute) { if (loadLibrary0(fromClass, new File(name))) { return; } throw new UnsatisfiedLinkError("Can't load library: " + name); } if (loader != null) { String libfilename = loader.findLibrary(name); if (libfilename != null) { File libfile = new File(libfilename); if (!libfile.isAbsolute()) { throw new UnsatisfiedLinkError( "ClassLoader.findLibrary failed to return an absolute path: " + libfilename); } if (loadLibrary0(fromClass, libfile)) { return; } throw new UnsatisfiedLinkError("Can't load " + libfilename); } } for (int i = 0 ; i < sys_paths.length ; i++) { File libfile = new File(sys_paths[i], System.mapLibraryName(name)); if (loadLibrary0(fromClass, libfile)) { return; } } if (loader != null) { for (int i = 0 ; i < usr_paths.length ; i++) { File libfile = new File(usr_paths[i], System.mapLibraryName(name)); if (loadLibrary0(fromClass, libfile)) { return; } } } // Oops, it failed throw new UnsatisfiedLinkError("no " + name + " in java.library.path"); }



发表评论
-
文件通道解析二(文件锁,关闭通道)
2017-05-16 23:17 1089文件通道解析一(读写操作,通道数据传输等):http://do ... -
文件通道解析一(读写操作,通道数据传输等)
2017-05-16 10:04 1182Reference定义(PhantomRefere ... -
文件通道创建方式综述
2017-05-15 17:39 1093Reference定义(PhantomReference,Cl ... -
文件读写方式简单综述后续(文件,流构造)
2017-05-14 23:04 1512Java Socket通信实例:http://donald-d ... -
文件读写方式简单综述
2017-05-14 11:13 1157Java Socket通信实例:http://donald-d ... -
FileChanne定义
2017-05-12 23:28 964文件读写方式简单综述:http://donald-draper ... -
SeekableByteChannel接口定义
2017-05-11 08:43 1262ByteChannel,分散聚集通道接口的定义(SocketC ... -
FileChannel示例
2017-05-11 08:37 1013前面我们看过socket通道,datagram通道,以管道Pi ... -
PipeImpl解析
2017-05-11 08:41 957ServerSocketChannel定义:http://do ... -
Pipe定义
2017-05-10 09:07 929Channel接口定义:http://donald-drape ... -
NIO-Pipe示例
2017-05-10 08:47 927PipeImpl解析:http://donald-draper ... -
DatagramChannelImpl 解析四(地址绑定,关闭通道等)
2017-05-10 08:27 817DatagramChannelImpl 解析一(初始化):ht ... -
DatagramChannelImpl 解析三(多播)
2017-05-10 08:20 1957DatagramChannelImpl 解析一(初始化):ht ... -
NIO-UDP实例
2017-05-09 12:32 1603DatagramChannelImpl 解析一(初始化):ht ... -
DatagramChannelImpl 解析二(报文发送与接收)
2017-05-09 09:03 1427DatagramChannelImpl 解析一(初始化):ht ... -
DatagramChannelImpl 解析一(初始化)
2017-05-08 21:52 1448Channel接口定义:http://donald-drape ... -
MembershipKeyImpl 简介
2017-05-08 09:11 947MembershipKey定义:http://donald-d ... -
DatagramChannel定义
2017-05-07 23:13 1247Channel接口定义:http://donald-drape ... -
MulticastChanne接口定义
2017-05-07 13:45 1170NetworkChannel接口定义:ht ... -
MembershipKey定义
2017-05-06 16:20 944package java.nio.channels; i ...
相关推荐
Java NIO的Selector实现主要由`sun.nio.ch.SelectorImpl`类完成,其内部使用了操作系统提供的多路复用I/O机制,如Linux的epoll、Windows的IOCP等。`select()`方法实际上会调用操作系统API,阻塞等待直到有事件发生。...
同步电机无传感HFI高频谐波注入模型及代码解析,PMSM永磁同步电机滑模观测器仿真模型研究,基于28035的典型HFI方案实现,详细解析参数实现过程与机理,工程实践与理论基础相结合的SOP代码应用,基于无传感HFI高频谐波注入模型的PMSM永磁同步电机同步控制技术:解析与代码实现,同步电机无传感HFI高频谐波注入模型+代码 PMSM永磁同步电机无传感器滑模观测器仿真模型(基于28035),典型的HFI方案; 代码为实际应用SOP代码,非一般玩票代码可比(非ti例程);解析说明详细描述了参数实现过程和实现机理,工程实践和理论基础结合。 ,核心关键词:同步电机;无传感HFI高频谐波注入模型;PMSM永磁同步电机;滑模观测器;仿真模型;28035;HFI方案;SOP代码;参数实现过程;实现机理;工程实践;理论基础。,基于HFI高频谐波注入的PMSM无传感器控制模型与SOP代码实现
一个采用thinkphp3.2开发的商城系统,无论从前台模板的设计,还是后台php的开,都具有非常好的学习价值。首先作为一套前台模板框架的学习总结成果。.zip项目工程资源经过严格测试运行并且功能上ok,可实现复现复刻,拿到资料包后可实现复现出一样的项目,本人系统开发经验充足(全栈全领域),有任何使用问题欢迎随时与我联系,我会抽时间努力为您解惑,提供帮助 【资源内容】:包含源码+工程文件+说明等。答辩评审平均分达到96分,放心下载使用!可实现复现;设计报告也可借鉴此项目;该资源内项目代码都经过测试运行;功能ok 【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目,也可基于此项目来扩展开发出更多功能 【提供帮助】:有任何使用上的问题欢迎随时与我联系,抽时间努力解答解惑,提供帮助 【附带帮助】:若还需要相关开发工具、学习资料等,我会提供帮助,提供资料,鼓励学习进步 下载后请首先打开说明文件(如有);整理时不同项目所包含资源内容不同;项目工程可实现复现复刻,如果基础还行,也可在此程序基础上进行修改,以实现其它功能。供开源学习/技术交流/学习参考,勿用于商业用途。质量优质,放心下载使用
无人驾驶车辆动力学模型验证与预测控制资料详解:视频教程及carsim2019与matlab2018应用,无人驾驶车辆动力学模型验证与预测控制资料详解:视频教程及carsim2019与matlab2018应用,无人驾驶的车辆动力学模型验证。 配套详细视频讲解。 配套无人驾驶车辆模型预测控制资料,有视频讲解carsim2019,matlab2018 ,无人驾驶车辆动力学模型验证;配套视频讲解;无人驾驶车辆模型预测控制;carsim2019视频讲解;matlab2018资料,无人驾驶车辆动力学模型验证与MPC控制技术详解视频
项目工程资源经过严格测试运行并且功能上ok,可实现复现复刻,拿到资料包后可实现复现出一样的项目,本人系统开发经验充足(全栈全领域),有任何使用问题欢迎随时与我联系,我会抽时间努力为您解惑,提供帮助 【资源内容】:包含源码+工程文件+说明等。答辩评审平均分达到96分,放心下载使用!可实现复现;设计报告也可借鉴此项目;该资源内项目代码都经过测试运行,功能ok 【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目,也可基于此项目来扩展开发出更多功能 【提供帮助】:有任何使用上的问题欢迎随时与我联系,抽时间努力解答解惑,提供帮助 【附带帮助】:若还需要相关开发工具、学习资料等,我会提供帮助,提供资料,鼓励学习进步 下载后请首先打开说明文件(如有);整理时不同项目所包含资源内容不同;项目工程可实现复现复刻,如果基础还行,也可在此程序基础上进行修改,以实现其它功能。供开源学习/技术交流/学习参考,勿用于商业用途。质量优质,放心下载使用
**基于多维度仿真的质子交换膜燃料电池模型构建与性能研究**,基于电化学经验模型与车辆参数,质子交换膜燃料电池稳态与动态建模仿真分析及特性研究,质子交膜燃料电池(#PEMFC) 稳态 AND 动态建模及仿真分析 Note:硕士lunwen复Xian;title:质子交膜燃料电池建模仿真与特性研究 内容: 1. 根据车辆结构参数和性能参数 确定燃料电池组相关参数, eg. 额定功率,最大功率等. (根据需求可省略,或改进); 2. 基于电化学经验模型,建立PEMFC 燃料电池的稳态数学模型; 3. 在稳态数学模型的基础上,考虑燃料电池双层电荷层现象以及电池电堆动态热传输的影响,建立PEMFC 电化学动态模型; 4. 建立稳态 AND 动态Simulink仿真模型; 5. 通过Signal Builder 模拟随时间阶跃下降的外加负载信号,Simulink仿真燃料电池的输出电压,输出功率,消耗功率,电池效率的变化曲线, 并详细分析了电池的稳态 动态响应特性以及影响因素; 6. 极其详尽的模型说明书(包含数学建模,simulink建模,模型结果分析,etc.) AND 图
项目工程资源经过严格测试运行并且功能上ok,可实现复现复刻,拿到资料包后可实现复现出一样的项目,本人系统开发经验充足(全栈全领域),有任何使用问题欢迎随时与我联系,我会抽时间努力为您解惑,提供帮助 【资源内容】:包含源码+工程文件+说明等。答辩评审平均分达到96分,放心下载使用!可实现复现;设计报告也可借鉴此项目;该资源内项目代码都经过测试运行,功能ok 【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目,也可基于此项目来扩展开发出更多功能 【提供帮助】:有任何使用上的问题欢迎随时与我联系,抽时间努力解答解惑,提供帮助 【附带帮助】:若还需要相关开发工具、学习资料等,我会提供帮助,提供资料,鼓励学习进步 下载后请首先打开说明文件(如有);整理时不同项目所包含资源内容不同;项目工程可实现复现复刻,如果基础还行,也可在此程序基础上进行修改,以实现其它功能。供开源学习/技术交流/学习参考,勿用于商业用途。质量优质,放心下载使用
推荐,YOLOV5目标检测全套视频课程,共7节。 1.任务需求与项目概述.mp4 2-数据与标签配置方法.mp4 3-标签转格式脚本制作.mp4 4-各版本模型介绍.mp4 5-项目参数配置.mp4 6-缺陷检测模型培训.mp4 7-输出结果与项目总结.mp4
智慧农业解决方案 -促进产业结构转型,突破传统业态.ppt
西门子200smart与昆仑通态锅炉换热站智能控制程序实例:涵盖模拟量读取、自动切换控制、时间段加热与温度设定、电能监控及Modbus通讯变频器控制。,西门子200smart与昆仑通态锅炉换热站程序实例:模拟量读取、自动切换与时间加热控制,Modbus通讯变频器电能管理解决方案,西门子200smart和昆仑通态锅炉热站程序项目实例,程序内有利用模拟量读取,运算时间自动切,水泵一用一备故障自动切,自动时间段加热,时间段设定温度,电能读取及算法 modbus通讯控制变频器。 ,核心关键词: 西门子200smart; 昆仑通态锅炉; 换热站程序项目; 模拟量读取; 运算时间自动切换; 水泵一用一备故障自动切换; 自动时间段加热; 设定温度; 电能读取; 算法; Modbus通讯; 控制变频器。,西门子Smart200程序控制锅炉换热站:智能换热与节能优化管理实例
项目工程资源经过严格测试运行并且功能上ok,可实现复现复刻,拿到资料包后可实现复现出一样的项目,本人系统开发经验充足(全栈全领域),有任何使用问题欢迎随时与我联系,我会抽时间努力为您解惑,提供帮助 【资源内容】:包含源码+工程文件+说明等。答辩评审平均分达到96分,放心下载使用!可实现复现;设计报告也可借鉴此项目;该资源内项目代码都经过测试运行,功能ok 【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目,也可基于此项目来扩展开发出更多功能 【提供帮助】:有任何使用上的问题欢迎随时与我联系,抽时间努力解答解惑,提供帮助 【附带帮助】:若还需要相关开发工具、学习资料等,我会提供帮助,提供资料,鼓励学习进步 下载后请首先打开说明文件(如有);整理时不同项目所包含资源内容不同;项目工程可实现复现复刻,如果基础还行,也可在此程序基础上进行修改,以实现其它功能。供开源学习/技术交流/学习参考,勿用于商业用途。质量优质,放心下载使用
相移格雷码解相位程序开发与条纹结构光编解码技术应用于单双目结构光三维重建系统,相移格雷码解相位程序开发:条纹结构光编解码技术助力单目双目结构光三维重建系统,相移格雷码解相位程序开发 条纹结构光编解码,可用于单目或双目结构光三维重建系统 ,相移格雷码解相位程序开发; 结构光编解码; 单目结构光; 双目结构光; 三维重建系统,相移格雷码解相位程序开发:单目双目结构光三维重建系统编解码技术
高集成伺服电机驱控芯片TMC9660例子代码
项目工程资源经过严格测试运行并且功能上ok,可实现复现复刻,拿到资料包后可实现复现出一样的项目,本人系统开发经验充足(全栈全领域),有任何使用问题欢迎随时与我联系,我会抽时间努力为您解惑,提供帮助 【资源内容】:包含源码+工程文件+说明等。答辩评审平均分达到96分,放心下载使用!可实现复现;设计报告也可借鉴此项目;该资源内项目代码都经过测试运行,功能ok 【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目,也可基于此项目来扩展开发出更多功能 【提供帮助】:有任何使用上的问题欢迎随时与我联系,抽时间努力解答解惑,提供帮助 【附带帮助】:若还需要相关开发工具、学习资料等,我会提供帮助,提供资料,鼓励学习进步 下载后请首先打开说明文件(如有);整理时不同项目所包含资源内容不同;项目工程可实现复现复刻,如果基础还行,也可在此程序基础上进行修改,以实现其它功能。供开源学习/技术交流/学习参考,勿用于商业用途。质量优质,放心下载使用
基于任务链的中小工厂数字化新路径 高效搭建有竞争力的数字工厂.pptx
光伏并网逆变器设计方案与高效实现:结合matlab电路仿真、DSP代码及环流抑制策略,光伏并网逆变器设计方案:结合matlab电路文件与DSP程序代码,实现高效并联环流抑制策略,光伏并网逆变器设计方案,附有相关的matlab电路文件,以及DSP的程序代码,方案、仿真文件、代码三者结合使用效果好,事半功倍。 备注:赠送逆变器并联环流matlab文件,基于矢量控制的环流抑制策略和下垂控制的环流抑制 ,光伏并网逆变器设计方案; MATLAB电路文件; DSP程序代码; 方案、仿真文件、代码结合使用; 并联环流抑制策略; 下垂控制的环流抑制,光伏并网逆变器优化设计:方案、仿真与DSP程序代码三合一,并赠送并联环流抑制策略Matlab文件
项目工程资源经过严格测试运行并且功能上ok,可实现复现复刻,拿到资料包后可实现复现出一样的项目,本人系统开发经验充足(全栈全领域),有任何使用问题欢迎随时与我联系,我会抽时间努力为您解惑,提供帮助 【资源内容】:包含源码+工程文件+说明等。答辩评审平均分达到96分,放心下载使用!可实现复现;设计报告也可借鉴此项目;该资源内项目代码都经过测试运行;功能ok 【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目,也可基于此项目来扩展开发出更多功能 【提供帮助】:有任何使用上的问题欢迎随时与我联系,抽时间努力解答解惑,提供帮助 【附带帮助】:若还需要相关开发工具、学习资料等,我会提供帮助,提供资料,鼓励学习进步 下载后请首先打开说明文件(如有);整理时不同项目所包含资源内容不同;项目工程可实现复现复刻,如果基础还行,也可在此程序基础上进行修改,以实现其它功能。供开源学习/技术交流/学习参考,勿用于商业用途。质量优质,放心下载使用
校园在线拍卖系统(源码+数据库+论文+ppt)java开发springboot框架javaweb,可做计算机毕业设计或课程设计 【功能需求】 按照校园在线拍卖系统的角色,我划分为了用户模块(拍卖者和用户)和管理员模块这两大部分。 拍卖者模块: (1)注册登录:用户注册为会员并登录校园在线拍卖系统;用户对个人信息的增删改查,比如个人资料,密码修改。 (2)竞拍商品管理:拍卖者可以对竞拍商品进行增删改查。 (3)竞拍订单管理:拍卖者可以看到用户提交的竞拍价格信息以及产品,可以对竞拍订单进行审核。 (4)评价订单管理:可以在此页面查看到用户提交的订单评价信息等。 (5)在线留言:可以回复用户的在线留言信息。 用户模块: (1)用户注册登录:用户注册为会员并登录校园在线拍卖系统;用户对个人信息的增删改查,比如个人资料,密码修改。 (2)拍卖资讯:用户可以在此模块中浏览系统发布的最新拍卖资讯。 (3)竞拍商品:用户可以查看到竞拍商品详情。 (4)在线竞拍:用户可以在竞拍商品下方点击立即竞拍,提交竞拍信息。 (5)在线留言:用户可以提交在线留言信息。 (6)竞拍订单:可以在线进行竞拍商品订单的支付。 (7)评价订单:支付后可以对订单进行评价。 管理员管理模块: (1)用户管理:管理员可以对前台上注册过的用户信息进行管控,对拍卖者信息进行审核,也可以对管理员信息进行管控。 (2)用户管理:管理员对系统用户的管理。 (3)商品分类管理:对商品进行分类管理。 (4)竞拍商品管理:对拍卖者发布的拍卖商品进行管理。 (5)竞拍订单管理:对用户提交的竞拍订单信息进行管理。 (6)评价订单管理:对用户的评价信息进行管理。 (7)在线留言管理:对用户的留言信息进行管理。 (8)系统管理:对通知公告、竞拍资讯、轮播图管理。 【环境需要】 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等版本均可; 【购买须知】 本源码项目经过严格的调试,项目已确保无误,可直接用于课程实训或毕业设计提交。里面都有配套的运行环境软件,讲解视频,部署视频教程,一应俱全,可以自己按照教程导入运行。附有论文参考,使学习者能够快速掌握系统设计和实现的核心技术。
项目工程资源经过严格测试运行并且功能上ok,可实现复现复刻,拿到资料包后可实现复现出一样的项目,本人系统开发经验充足(全栈全领域),有任何使用问题欢迎随时与我联系,我会抽时间努力为您解惑,提供帮助 【资源内容】:包含源码+工程文件+说明等。答辩评审平均分达到96分,放心下载使用!可实现复现;设计报告也可借鉴此项目;该资源内项目代码都经过测试运行;功能ok 【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目,也可基于此项目来扩展开发出更多功能 【提供帮助】:有任何使用上的问题欢迎随时与我联系,抽时间努力解答解惑,提供帮助 【附带帮助】:若还需要相关开发工具、学习资料等,我会提供帮助,提供资料,鼓励学习进步 下载后请首先打开说明文件(如有);整理时不同项目所包含资源内容不同;项目工程可实现复现复刻,如果基础还行,也可在此程序基础上进行修改,以实现其它功能。供开源学习/技术交流/学习参考,勿用于商业用途。质量优质,放心下载使用
二极管箝位型三电平逆变器与NPC三电平逆变器的SVPWM及中点电位平衡调制研究——基于MATLAB Simulink仿真模型,二极管箝位型与NPC三电平逆变器研究:SVPWM及中点电位平衡调制的技术挑战与MATLAB仿真模型参考,二极管箝位型三电平逆变器,NPC三电平逆变器。 主要难点:三电平空间矢量调制(SVPWM),中点电位平衡调制等。 MATLAB Simulink仿真模型,可提供参考文献。 ,二极管箝位; NPC三电平; 三电平空间矢量调制(SVPWM); 中点电位平衡调制; MATLAB Simulink仿真模型,三电平逆变器技术研究:SVPWM调制与中点电位平衡仿真分析