??xml version="1.0" encoding="utf-8" standalone="yes"?>
互斥性体现在c锁或者对象锁上,每个对象自n都包含一个监视器Q该监视器是一个每ơ只能被一个线E所获取q入的界区Q可以通过wait和notify来退出和准入临界区。可?/font>看出q是一个生产?消费者的模型。而Concurrent包中的LockZ能够获得更好的性能和更好的扩展性,以及不依赖于关键字的可读代码Q自己实Cq样一个生产消贚w列,?/font>是AbstractQueuedSynchronizerQ被UCؓAQS的机制。每个Lock都内|了一个AbstractQueuedSynchronizer。需要说明的是AbstractQueuedSynchronizer内部实现采用了CAS机制Q通过getState, setState, compareAndSetState讉K控制一?2bit int的Ş式进行互斥?/font>
那么可见性是如何保证的呢Q?/font>
对于关键字的同步机制Q其实可见性就是线E和d之间的同步时机问题。共?个时间点需要注意:
1 获取或释攄?对象锁的时候。Thread保证reload/flush全部变更
2 volatile是flush on write或者reload on read
3 当线E首ơ访问共享变量时Q可以得到最新的l果?br />
题外Q所以在构造方法中公布this时很危险的。简单的_是构造时不逃脱M变量Q不开启新的线E,只做装。关于安全构造,请参?br />
http://www.ibm.com/developerworks/cn/java/j-jtp0618/#resources
4 U程l束Ӟ所有变更会写回d
关于Concurrent Lock如何实现可见性的问题QDoug Lea大侠Q只在他的论文中提到Q按照JSR133QUnsafe在getState, setState, compareAndSetState时保证了U程的变量的可见性,不需要额外的volatile支持Q至于具体这些native做了哪些magic׃得而知了,MQ最后的contract是保证lock区间的共享变量可见性。开发团队被逼急了p样回{:
There seems to be a real reluctance to explain the dirty details. I think the question was definitely understood on the concurrent interest thread, and the answer is that synchronized and concurrent locking are intended to be interchangable in terms of memory semantics when implemented correctly. The answer to matfud's question seems to be "trust us.”
不过q个地方的确是开发团队给我们用户qh的地方,在同样应用了CAS机制的AtomiccMQ都内嵌了volatile变量Q但是再lock块中Q他告诉我们可以保证可见性?/font>
感兴的同学可以下面的两个thread和Doug Lea的thesisQ?br />
http://altair.cs.oswego.edu/pipermail/concurrency-interest/2005-June/001587.html
http://forums.sun.com/thread.jspa?threadID=631014&start=15&tstart=0
http://gee.cs.oswego.edu/dl/papers/aqs.pdf
文gpȝ无非是文g的存取和l织l构?br /> 讉K一个文件系l的API也应该是写,读,定位ҎQPathname?/URI?Q?/p>
FTPClient针对文g的保存和获取各提供了两个ҎQ分别是Q?br />
两个Ҏ貌似相同Q实际不同,q回的那个因ؓ不能马上处理,所以需要用h工调用completePendingCommandQ而另一个传递流q去的则不需要。可能有同学已经遇到q这个问题了Q读写第一个文件时L正确的,当相同APIdW二个文件时Qblock住了。这是因为FTPClient要求在进行流操作之后执行completePendingCommandQ以保处理完毕,因ؓ处理不是即时的Q所以也没有办法不手工调用completePendingCommand。问题是开发者把不返回流的方法末֊上了completePendingCommandQ如果不看代码可能根本不知道?br /> 文上说Q?br />
但是q样仍然q是让h有点困惑Qؓ什么都是存?d的方法,有时候要调用completePendingCommandQ有时候不调用Q更严重的问题是completePendingCommand调用了getReplyQ如果一个命令通过socket stream传了q去但是没有getReplyQ即没有completePendingCommandQ那么下ơ发命oӞ会受到本次q回码的q扰Q得到无效的响应。而如果在completePendingCommand之后又进行了一ơ无辜的completePendingCommandQ那么因为FTP Server上没有Reply了,׃block。所以completePendingCommandq不是可以随意添加的?/p>
现在出现了两个问题:
1 completePendingCommand很容易多出来或遗?br />
2 昑ּ调用completePendingCommand暴露了底层实玎ͼl用户带来不便,用户只想要InputStream或者OutputStream
Z解决q个问题Q可以对InputStreamq行扩展Q徏立一个ReplyOnCloseInputStreamQ如下:
q样装之后QFTPClient的用户只需要正常在处理完流之后关闭卛_Q而不必暴露实现细节。保存文件也可以用相同的Ҏ装OutputStream?/p>