我有一個OpenGL ES 2.0應用程序。內它,我有一個包含像這樣另一類型的對象的一個陣列(這被簡化爲問題)的類:Java:保護一個對象不被多線程訪問
public class StoreList(){
thisList StoreItems[];
public StoreList(int nuberOfItems){
thisList = StoreItems[numberOfItems];
}
}
最初,我該應用中填充列表,然後在某些點(當用戶在「存儲」場景),它可能被添加到列表中的新項目,因此,舉例來說,這個名單可以是這個樣子:現在
Before After inserting object 'Fish' into index 1
Index 0 - Dog Index 0 - Dog
Index 1 - Fox Index 1 - Fish
Index 2 - Bird Index 2 - Fox
Index 3 - Snake Index 3 - Bird
Index 4 - Snake
,這個名單是通過迭代出於各種原因。例如,用於渲染,更新它們的位置等。
我遇到的問題是,我的應用程序使用2個線程 - GL渲染線程和Main/UI線程。
當用戶執行某個動作時,UI線程調用插入額外項目的'insertObject'方法,如上所述。然而,渲染線程很樂意做它的事情,如果它是在索引1處同時渲染對象'insertObject'被調用,那麼它開始導致問題(列表中的每個對象具有不同數量的openGL四邊形來繪製並且繪製的數字包含在對象本身的一個變量中),所以如果索引1處的原始對象有5個四邊形,並且新對象只有4個,那麼它開始嘗試繪製第五個四邊形,並且我們得到所有問題的方式(索引超出範圍)。
render方法,updateLogic方法和onTouchEvent方法都被聲明爲synchronized,但我仍然遇到這個問題。
我不確定如何去確保這個對象(StoreList的實例及其中的所有內容,它是'thisList'數組)只能從一個線程一次更新。
我看到的有關併發問題的問題都是關於保護一個方法不被多線程而不是對象調用,所以我有點困惑。
希望得到任何指導。
也許一個['CopyOnWriteArrayList'](http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/CopyOnWriteArrayList.html)會更適合你嗎? – RealSkeptic
最簡單的方法:通過['Lock'](https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/locks/Lock.html)保護列表。每個想要讀取或寫入列表的方法都需要首先獲取「Lock」。稍微複雜一些:嘗試使用['@ synchronized'](https://docs.oracle.com/javase/tutorial/essential/concurrency/syncmeth.html)。只要'@ synchronized'內沒有使用阻塞結構(比如'wait()'),就可以完成這項工作。 – Turing85
Thanks @ Turing85,你的意思是在所有將從列表中讀/寫的代碼上使用同步塊? (使用列表本身作爲鎖定對象?)我只是想知道我是否可以簡單地聲明任何讀取/寫入列表的同步方法?我剛剛那樣做,迄今沒有崩潰(經過大約30次測試)。我也不確定你的意思是'@synchronized'。你能提供一個例子嗎?謝謝你的幫助。 – Zippy