作者LaPass (LaPass)
看板java
標題Re: [問題] synchronized 和 multi thread
時間Tue Oct 4 23:27:15 2011
※ 引述《jehovah (Lucius)》之銘言:
: 大家好, 小弟對multi thread還不熟悉, 想請教一個問題
: 目前我有A, B兩條thread, 以及一個公用的arraylist
: A thread會做以下的工作:
: arraylist.remove(old_index);
: ...一些運算
: arraylist.add(new_index, obj);
: B thread則會對arraylist作get
: 因此A在作add前, B有機會IndexOutOfBounds
: 我查了synchronized修飾字,
: 將A的工作用synchronized包起來, 可是沒有幫助
: synchronized(arraylist){
: ...
: }
: 我是希望鎖住arraylist這個物件, 而不是操作這物件的Method
: 請問一般來說, 這種狀況如何處理較恰當?
: 可否給我點建議, 或是該往哪個方向去查..謝謝:)
ReentrantLock arrLock = new ReentrantLock();
ArrayList<Object> arrList = new ArrayList();
public Object arrGet(int i)
{
arrLock.lock();
try
{
return arrList.get(i);
}
finally
{
arrLock.unlock();
}
}
public void arrSet(Object obj)
{
arrLock.lock();
try
{
arrList.add(obj);
}
finally
{
arrLock.unlock();
}
}
關鍵字:Lock
這是比synchronized麻煩,但比synchronized的彈性更大的東西
例如:
if (arrLock.trylock())try
{
//TODO 成功鎖定物件後要做的事
}
finally
{
arrLock.unlock();
}
else
{
//TODO 萬一物件被別條執行緒鎖定時要做的事
}
Thinking in JAVA有比較詳細的說明
另外,這個東西使用上有個要注意的地方
根據自己使用上的經驗
如果在try中噴出錯誤的話,仍然跑finally中的程式碼去解鎖
但如果執行緒在中途被砍掉的話,有可能就一直鎖在那邊
所以請不要在執行緒還在try區塊當中時,去砍執行緒
(那時候把lock設成static,又遇到程式出錯誤,去用android的工具中斷掉程式
再次執行程式就發現lock還被鎖著)
可能有防止的辦法吧....
但因為我沒砍執行緒的需求,就沒深入研究
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 125.233.156.87
→ LaPass:補一下 java.util.concurrent 底下有許多執行緒安全的容器 10/05 00:29
推 jehovah:謝謝..這個東西好酷 10/05 00:32
→ LaPass:可用,你可以去翻看看有沒有適合的可用 10/05 00:33
推 tomap41017:推concurrent,不需要自己寫 10/06 01:20
推 jehovah:謝謝解答, 我用CopyOnWriteArrayList可以解掉問題:) 10/07 01:47
→ jehovah:另外我有疑問vector可否代替CopyOnWriteArrayList?差異是? 10/07 01:50