[英]Simple question on java synchronization
我想使用舊方式(int i ...)循環遍歷java List,因為對於給定的i和循環迭代,我想訪問相對於i的幾個元素。 然后我不能使用(對象o:對象)列表迭代器。
在執行時,如何確保沒有其他代碼可以訪問列表?
我試過了
synchronized(path.getPoints()){
for (int i = 0; i < path.getPoints().size(); i++){
...
}
}
其中path是保存列表的對象,也是
synchronized(path){
for (int i = 0; i < path.getPoints().size(); i++){
...
}
}
並且
synchronized(this){
for (int i = 0; i < path.getPoints().size(); i++){
...
}
}
其中“this”是想要在沒有同步問題的情況下完全呈現路徑的渲染器。
提前致謝,
馬丁
在執行時,如何確保沒有其他代碼可以訪問列表?
通過確保所有其他代碼也同步在同一對象上。 synchronized(path.getPoints())
是最佳選擇。 getPoints()
返回通過Collections.synchronizedList()
包裝的列表可能是一個好主意 - 然后您不需要顯式同步簡單的get()
或add()
調用,但仍需要迭代的同步。
復雜? 是啊。 這就是共享內存多線程編程被認為非常困難的原因。
您可以通過使用寫入方法的副本完全避免同步。 它有相關的成本,但您可以接受: http : //download.oracle.com/javase/6/docs/api/java/util/concurrent/CopyOnWriteArrayList.html
您可以使path.getPoints()同步並返回點列表的副本(或者可能是數組)。 然后,在迭代它時不需要同步。 如果point是私有的,您可以輕松確保Path中訪問它的所有方法也是同步的。
“synchronized(this)”(其中“this”是您的渲染器)確保沒有其他線程可以同時運行相同的渲染器; 但是,其他線程可以訪問列表和“路徑”對象。
你最好的做法可能是確保使用集合( path.getPoints()
)進行寫入的任何事情都是在同步塊(在同一個集合中)這樣做,以便消費者(例如只讀)想要在其上使用枚舉器的集合也可以通過在集合上使用synchronized塊來安全地執行此操作。
我建議你寫這個。
List<Point> points = path.getPoints()
synchronized(points){
for (Point point: points){
...
}
}
這確保getPoints()不會返回不同的東西並簡化代碼恕我直言。
我還會使用@Michaels建議每次訪問getPoints()時進行同步,或者使其成為Collectons.synchronizedList()或者像CopyOnWriteArrayList()這樣的線程安全列表
注意:如果使用線程安全列表,則可能不需要同步它。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.