Posted on 2009-04-27 18:22
沙漠中的魚(yú) 閱讀(242)
評(píng)論(0) 編輯 收藏 所屬分類(lèi):
Java基礎(chǔ)
事件監(jiān)聽(tīng)的安全性
如下代碼,在用Vector進(jìn)行不安全的迭代時(shí),另外一個(gè)線程對(duì)Vector的對(duì)象進(jìn)行添加或刪除時(shí),會(huì)拋出會(huì)拋出 ConcurrentModificationException異常。
Vector<Listener> v;
for (int i=0; i<v.size(); i++)
v.get(i).eventHappened(event);
java.util.concurrent 中的 CopyOnWriteArrayList 類(lèi),能夠幫助防止這個(gè)問(wèn)題。它實(shí)現(xiàn)了 List,而且是線程安全的,但是它的迭代器不會(huì)拋出 ConcurrentModificationException,遍歷期間也不要求額外的鎖定。這種特性組合是通過(guò)在每次列表修改時(shí),在內(nèi)部重新分配并拷貝列表內(nèi)容而實(shí)現(xiàn)的,這樣,遍歷內(nèi)容的線程不需要處理變化 —— 從它們的角度來(lái)說(shuō),列表的內(nèi)容在遍歷期間保持不變。雖然這聽(tīng)起來(lái)可能沒(méi)效率,但是請(qǐng)記住,在多數(shù)觀察者情況下,每個(gè)組件只有少量偵聽(tīng)器,遍歷的數(shù)量遠(yuǎn)遠(yuǎn)超過(guò)插入和刪除的數(shù)量。所以更快的迭代可以補(bǔ)償較慢的變化過(guò)程,并提供更好的并發(fā)性,因?yàn)槎鄠€(gè)線程可以同時(shí)迭代列表。
事件監(jiān)聽(tīng)初使化風(fēng)險(xiǎn)
事件監(jiān)聽(tīng)器允許"this"轉(zhuǎn)義
失效的監(jiān)聽(tīng)
public void processFile(String filename) throws IOException {
cancelButton.registerListener(this);
// open file, read it, process it
// might throw IOException
cancelButton.unregisterListener(this);
}
當(dāng)讀入文件時(shí),產(chǎn)生異常,會(huì)造成取消注冊(cè)事件不能被執(zhí)行,取消登記的操作應(yīng)當(dāng)在 finally 塊中進(jìn)行,這樣,processFile() 方法的所有出口都會(huì)執(zhí)行它。