我正在看一些在Java 6及更高版本中導致問題(死鎖)的代碼,但不是在Java 1.5中。Java 6同步中的更改?
BMP豆:
private MyClass m_c;
public String ejbCreate(String id) throws CreateException, MyException
{
try
{
m_c = Singleton.getInstance().getObj(id);
}
catch (MyException e)
{
synchronized (Singleton.getInstance())
{
//check again
if (!Singleton.getInstance().hasObj(id)) {
m_c = new MyClass(id);
Singleton.getInstance().addObj(id, m_c);
}
else {
m_c = Singleton.getInstance().getObj(id);
}
}
}
}
辛格爾頓:
private Map objCache = new HashMap();
private static Singleton INSTANCE = new Singleton();
public static Singleton getInstance() {
return INSTANCE;
}
public void addObj(String id, MyClass o)
{
if (this.objCache.containsKey(id)) {
this.objCache.remove(id);
}
this.objCache.put(id, o);
}
public MyClass getObj(String id) throws Exception
{
MyClass o = null;
o = (MyClass)this.objCache.get(id);
if (o == null) {
throw new MyException("Obj " +id+ " not found in cache");
}
return o;
}
public boolean hasObj(String id)
{
return this.objCache.containsKey(id);
}
的證據更表明,將同步圓整的try/catch解決了使用Java 6
死鎖時顯然可以有一個或多個線程調用
Singleton.getInstance().getObj(id)
沒有獲得鎖而另一個線程擁有鎖並正在執行同步塊中的代碼,但即使在考慮JSR-133中詳述的內存同步之後,它看起來並不像這種情況下應該有任何問題。
我知道我沒有解釋說這是一個僵局,而且它不是很理想的只繪製一張圖片,但繪製整個圖片需要一個非常大的畫布。
我已經看過Java 6發行版的註釋,並且唯一與聲音相關的區域圍繞着無爭用的同步,但我不知道在這種情況下這是否意義重大。
謝謝你的幫助。
得到你需要一個僵局,然後再嘗試一次在不同的線程來獲得兩個或更多的鎖。單獨一個鎖就不會出現死鎖。你能否展示使用另一個鎖以及如何以不同的順序獲得這些鎖? –
注:還有一個問題,你可以進入一個無限循環,如果你更新以不安全的方式一個地圖。這一直在那裏。我會考慮整個代碼線程安全的,如果你需要的併發訪問,使用的ConcurrentMap(Java 5.0中加入) –
順便說一句,如果你有一個真正的僵局,這一切都使用內置'synchronized'關鍵字,那麼一個線程轉儲會實際檢測到這個死鎖並告訴你。如果你沒有看到,這是彼得理論的有力證據。 – yshavit