在JDK1.4.2中加入了对NIO的支持,掌握其中的Selector个人认为是能实现好NIO的关键。
Selector是用来获取注册在其中的channel的相关事件的发生,也就是accept,read和write。selector中有3个key set。
key set:包含代表所有在其中注册的channel,可以通过selector.keys()得到。
selected-key set:包含所有被检测到有关注的操作已经就绪的key,通过selector.selectedKeys得到。
cancelled-key set:包含所有已经被cancel,但是还没有channel还没有deregister的key,这个集合是不能直接被访问的。
key通过调用channel的register方法被加入到key set中。被取消的key在select的时候会被从相应的key set中移除。
key set自身是不可以直接进行修改的。
无论是通过调用channel的close方法还是调用key的cancel方法,key都会被放置到canceled-key set中。取消的key会将其channel在下一次select时将注册撤销,同时将key从所有的key set中移除。
key在执行select操作时被加入到selected-key set中。在selected-key
set中的key可以通过调用iterator的remove方法,将其从selected-key
set中移除,不能通过其他的办法将其从selected-key set中移除。
通过selector的3个方法select(阻塞选择,直到有关心的事件发生时退出阻塞),selectNow(不阻塞选择),select(long)(指定超时选择,超时到达或者有关心事件发生时退出阻塞),来获取关心事件的发生。其执行步骤分为以下3步:
1、将存在于canceled-key set中的key从所有的key set中移除,撤销注册的channel,清空canceled-key set。
2、地层操作系统检查是否有关心的事件发生,当有关心的事件发生时,首先检查channel的key是否已经存在于selected-key
set中,如果不存在,则将其加入到selected-key set中去,同时修改key的ready-operation
set来表明当前ready的操作,而以前存在于ready-operation
set中的信息会被删除。如果对应的key已经存在于selected-key set中,这直接修改其ready-operation
set来表明当前ready的操作,删除原来ready-operation set中的信息。
3、如果在第二步中有加入到canceled-key set中的key,在这一步会执行第一步的操作。
selector自身是线程安全的,而他的key
set却不是。在一次选择发生的过程中,对于key的关心事件的修改要等到下一次select的时候才会生效。
另外,key和其代表的channel有可能在任何时候被cancel和close。因此存在于key
set中的key并不代表其key是有效的,也不代表其channel是open的。如果key有可能被其他的线程取消或关闭channel,程序必须小
心的同步检查这些条件。
阻塞了的select可以通过调用selector的wakeup方法来唤醒。
posted @
2005-04-26 10:06 非飞 阅读(1476) |
评论 (3) |
编辑 收藏
在JavaScript中,可以通过window.location来获取url地址。但是window.location是一个对象,没有办法直接从里面获取出我们需要的参数。通常的做法就是使用一个隐藏的<input>,通过将window.location负值给input。其目的就是为了将location转换成String。写的过程中总是觉得太复杂了,后来发现使用document.URL就可以解决这个问题。
posted @
2005-04-18 15:52 非飞 阅读(2289) |
评论 (3) |
编辑 收藏
下载了一个Action Script Viewer 4.0对原来的swf文件进行反编译,虽然有的movie clip会出现一点问题,但是总的来说效果还是不错的,而且操作相当的简单。
1)使用ASV打开要进行反编译的SWF文件;
2)File-->export rebuild data。这时将swf文件分拆成单个的swf文件;
3)打开flash,创建一个空的fla文件;
4)File-->Import...-->Import to Library 将前面导出的swf文件导入,如果swf文件太多flash会报错,可以通过分批导入文件来绕过这个错误;
5)将新建的swf文件保存为rebuild.fla,并且3)导出的文件在同一目录;
6)运行3)产生的一个rebuild.jsfl文件,一切搞定。
posted @
2005-04-04 03:32 非飞 阅读(970) |
评论 (1) |
编辑 收藏
中午收到老姐来的电话,电话里她是一遍一遍又一遍的在我耳边唠叨,说,“不管你怎么忙,有多少东西要写,一定要按时睡觉”。还列出了一堆要按时睡觉的理由。其实谁不知道应该要按时睡觉,可是作为写程序的程序员来说,要真想做到这一点实在是难,难,难呀!
要按时睡觉的理由:
从人的排毒期入手:晚间11:00--1:00,肝的排毒期(必须在睡觉中进行)
从人的睡眠最佳时段入手:1:00--4:00,人的睡眠是质量最高的
不知道各位有谁是有正常的生活习惯的,能不能说一说你是怎么做到的。。。
posted @
2005-03-23 15:25 非飞 阅读(752) |
评论 (3) |
编辑 收藏
做了这么久的软件,从来就没有好好的学习过设计模式。写代码,做设计的时候都是稀里糊涂。做出来的设计,都会不同程度的让自己感觉到不安。这可能就是《设计模式精解》书中所说那种直觉吧。
引用:
留意你的知觉
出自本能的直觉能对设计质量做出令人惊讶的预测。所谓“出自本能的直觉”,是指当你看到某些不喜欢的东西时,你胃部的感觉。我知道这听起来并不科学(而且它的确不科学),但我的经验总是向我证明:当我从直觉上不喜欢一个设计时,一个更好的设计一定就躺在角落里。
Facade模式:关键特征
意图:希望简化现有系统的使用方法。你需要定义自己的接口。
问题:只需要使用一个复杂系统的一个子集。或者,需要用一种特殊的方式与系统交互。
解决方案:Facade向客户展现使用现有系统的一个新的接口。
参与者与协作者:向客户展现一个定制的接口,让客户更容易地使用现有系统。
效果:Facade模式简化了对所需子系统的使用。但是,由于Facade并不完整,因此某些功能对于客户可能是可用的。
现实:1)定义一个(或一组)新的类来提供所需要的接口。
2)让新的类使用现有的系统。
Facade模式使用于以下情况:
- 不需要使用一个复杂系统的所有功能,并且可以创建一个新的类来包容访问原有系统的接口的一个子集(通常它就是)比原始系统AP简单得多。
- 希望包装或隐藏原有系统。
- 希望使用原有系统的功能,并且希望增加一些新的功能。
- “编写一个新的类”的代价小于“让所有人学会使用原有系统”或“在未来维护整个系统”所需的代价
posted @
2005-03-13 23:41 非飞 阅读(1057) |
评论 (0) |
编辑 收藏
一个项目通常分为表示层、业务逻辑层和持久层,这是最为常见的三层结构。在组织团队进行项目开发的时候,选择如何分工对版本控制有很大的影响。团队在做开发的时候一般有两种模式:按层开发和按功能开发。
按层开发(本人赞同的模式)
在这种开发模式下,每个开发人员的目录结构相对固定和独立。对于CVS这类按文件夹来控制权限的版本控制服务器来说,比较容易实现对开发人员权限的划分,不易出现文件不同步而导致的版本混乱。
另外,这种开发模式下,更能集中开发人员的注意力,不需要了解太多与本层无关的其他技术。将精神全部集中在如何实现本层的功能上,更有利于写出功能强大,运行稳定的代码。例如:开发业务逻辑层的开发人员,他不可避免的会写很多逻辑上基本上一致的代码,在写代码的过程中,就能从中找出一些相对的共性,将公共的代码进行抽象,从而避免了出现大量的重复代码。由于工作范围相对较小,能有更多的时间去学习相关方面的最新技术和解决方案,并应用到程序中,能使程序在实现方式上较为先进、优越。
老天是公平的,万物有其好的一面也必然有其不好的一面,这种开发模式也不能例外。对于需求不明确,无法定义相对固定的对外接口时,这中按层开发的模式就有其无法避免的一个问题。各层开发人员需要在开发的过程中,反覆的修改接口,以便适应于变化了的需求。这必然就导致逻辑处理部分代码要做相应的修改。
按功能开发(本人持保留态度)
这种开发模式下,开发人员的目录结构基本是项目的完整目录接口,他们需要到各层去编写对应他们所开发的模块的所有代码。对于CVS这类版本控制服务器来说,基本上是无法做到对开发人员权限的界定。很容易造成版本控制混乱,导致文件版本不同步,是在开发过程中使用了公共文件的开发人员不能保证同步。例如:一个文件为多个开发人员所共同维护,开发人员各自都需要在其中添加自己功能所需要部分的代码。这样很容易出现多个人同时修改一个文件的情况,导致文件不同步而造成的版本混乱。
另外,这种开发模式对开发人员的技术要求相对较高,它要求开发人员掌握各层中所需要的技术。从界面显示到数据持久化,甚至到网络通信都需要一个开发人员去实现。在功能实现架构不是很确定的情况下,程序代码中将会出现大量的重复代码,因为每个人都有自己的实现机制,而逻辑处理相同或相近的情况在同一层中出现频率又比较高。导致程序的整体结构不统一,尽管层次结构相同。使得程序日后维护极度困难,大大的提高了维护成本。由于开发人员牵涉使用的技术过多,也很难保证程序实现方式的先进性和优越性。
posted @
2005-03-03 21:06 非飞 阅读(788) |
评论 (0) |
编辑 收藏
网上一大堆关于PO,POJO,DTO,VO等等对象的讨论,通常都是各持己见,公说公有理,婆说婆有理,讨论到最后也没有什么定论。今天看到一个应用的代码,发现其讲PO直接做为VO(view object)在表示层使用。只从代码上讲,这样做确实省去了跟多操作。不用重复的做对象的赋值、构造。但是会过头来看,这样无疑增加了代码的耦合性。做一个简单的假设,如果对持久层的PO进行了修改,相应的使用PO做为对应的VO(value object)业务逻辑层和使用PO最为VO(view object)的表示层都必须做相应的修改,如此的应用给代码的维护带来了很大的负担,可谓是一动则百动。
在J2EE应用开发中,是不应该出现这中PO共享使用的方式的。实体对象不应该被跨层使用,各层维护自己的实体对象。这点看书我想大家都知道,而在实际应用中很多人都选择不遵循这一规则。(在使用hibernate时有所不同,引用:“
不过由于Hibernate的强大功能,例如动态生成PO,PO的状态管理可以脱离Session,使得在应用了Hibernate的J2EE框架中,PO完全可以充当VO,因此我们下面把PO和VO合并,统称为PO。”引文:
结合struts和hibernate谈J2EE架构的数据表示。)出现这总现象,我想原因只有一个就是贪图了一时的省事,在一次性应用开发中,相对的业务对象改动可能性相当的少,很多时候在做项目的时候并不会出现预料不到的改变,没有必要去管理一大堆各式各样的实体对象,这样就自然的导致了PO在各层中共享使用。可是就我目前接触到的项目基本上没有需求是如此明确的,通常需求都是在不断的改变,甚至有时到了最后发版的时候,一些客户都会提出修改需求的要求。另外就是自做需求的情况就更是如此了,这种项目的需求是不断的在变化的。为了保证项目的适应性和可扩展性,就必须保证各层之间的相对独立,尽可能降低耦合度。
posted @
2005-03-01 12:40 非飞 阅读(865) |
评论 (2) |
编辑 收藏