簡體   English   中英

關於java同步的簡單問題

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM