2012-12-31 115 views
2

我是Java的新手,在嘗試實現一個簡單的遊戲時遇到了一個問題。 當前遊戲的前提是,計時器用於添加汽車,並且更頻繁地更新汽車的運動。一輛汽車可以通過觸摸進行選擇,並通過繪製路徑進行指導。更新功能將沿着路徑移動汽車。兩個線程訪問同一個LinkedList

現在,遊戲的IndexOutOfBoundsException異常崩潰,我幾乎可以肯定,這是因爲偶然,當汽車重新選擇,電流路徑擦拭,並允許繪製了一條新路。該路徑存儲爲LinkedList,並在車輛被碰觸時清除。

我想象一下,如果通過觸摸事件清除路徑,而計時器線程正在更新汽車沿路徑的移動,這就是錯誤發生的地方(也有類似的其他問題,可能會出現兩個線程訪問此一個列表

我的問題,在Java中,處理這個問題的最佳方式是什麼?是否應該使用特定類型的列表而不是LinkedList,或者是否存在諸如C++中的Mutex之類的對象,其中在使用它的同時,我可以保護這個列表嗎?

+0

需要看到一些代碼 – Woot4Moo

回答

8

在Java中,這通常使用synchronization

一個小例子可能是這個樣子:

LinkedList list = //Get/build your list 

public void doStuffToList() 
{ 
    synchronized(list) 
    { 
     //Do things to the list 
    } 
} 

public void clearList() 
{ 
    synchronized(list) 
    { 
     list.clear(); 
    } 
} 

此代碼不會讓,如果有另一個線程當前列表當時在操作執行清除操作。請注意,這會導致阻塞,所以要小心死鎖。

另外,如果您的List是,你已經建立了自己的一類,它可能是有道理的,使數據結構線程安全本身:

public class SynchroLinkedList 
{ 
    //Implementation details 

    public synchronized void doThingsToList() 
    { 
     //Implementation 
    } 

    public synchronized void clearList() 
    { 
     //Implementation 
    } 
} 

這兩種方法能有效的工作方式相同,但第二個線程的安全性被抽象爲數據類型,這很好,因爲當你使用這個列表時,你不必擔心線程安全。

+0

感謝您的迅速答覆,這正是我一直在尋找的。第二種解決方案非常適合我目前的實施,它的作用就像一個魅力! – user1939844

+0

您可能仍需要擔心需要原子操作的組合操作(例如迭代)時的線程安全性。 – assylias

0

而是重新創建你自己的線程安全列表實現的,你有幾個內置的選項,主要有:

  • 使用synchronized list

    List list = Collections.synchronizedList(new LinkedList()); 
    

    請注意,您需要在同步列表(synchronized(list) { })用於迭代和其他需要原子化的組合操作)

  • 使用一個th請閱讀安全集合,例如CopyOnWriteArrayListConcurrenLinkedQueue,如果您不需要訪問列表中間的項目,但只需要添加迭代,則這可能是一個不錯的選擇。

    請注意,根據您的使用情況,CopyOnWriteArrayList可能會有性能損失,特別是如果您經常添加項目(即每隔幾微秒)並且該列表可能變大。

相關問題