سؤال

لست متأكدا إذا كان هذا هو الطريق الصحيح لمزامنة ArrayList.

لدي ArrayList in_queue والتي يتم تمريرها من registerInQueue وظيفة.

ArrayList<Record> in_queue = null;

public void registerInQueue(ArrayList in_queue)
{
    this.in_queue = in_queue;
}

الآن أنا أحاول أن تزامن ذلك.هذا sychronizing بلدي in_queue الكائن بشكل صحيح ؟

List<Record> in_queue_list = Collections.synchronizedList(in_queue);

synchronized (in_queue_list) {
    while (in_queue_list.size() > 0) {
        in_queue_list.remove(0);
    }
}
هل كانت مفيدة؟

المحلول

أنت مزامنة مرتين ، التي لا طائل وربما يبطئ كود:التغييرات أثناء بالتكرار على قائمة تحتاج إلى synchronnization على كامل العملية التي تقومون به مع synchronized (in_queue_list) باستخدام Collections.synchronizedList() لزوم له في هذه الحالة (يخلق المجمع مزامنة العمليات الفردية).

لكن, منذ كنت في إفراغ قائمة تماما ، يتحرك إزالة العنصر الأول هو أسوأ طريقة ممكنة للقيام بذلك ، sice لكل عنصر جميع العناصر التالية يجب أن تكون نسخ, مما يجعل هذا O(n^2) عملية بطيئة فظيعة أكبر القوائم.

بدلا من ذلك, ببساطة الاتصال clear() - لا التكرار الحاجة.

تحرير: إذا كنت في حاجة إلى واحدة-طريقة المزامنة Collections.synchronizedList() في وقت لاحق, ثم وهذا هو الطريق الصحيح:

List<Record> in_queue_list = Collections.synchronizedList(in_queue);
in_queue_list.clear(); // synchronized implicitly, 

ولكن في كثير من الحالات ، واحدة-طريقة التزامن غير كافية (على سبيل المثاللجميع التكرار ، أو عندما تحصل على قيمة تنجز بناء على ذلك ، واستبدالها النتيجة).في هذه الحالة يجب عليك استخدام التزامن اليدوي على أي حال, لذا Collections.synchronizedList() هو فقط عديمة الفائدة النفقات الإضافية.

نصائح أخرى

وتبحث في المثال الخاص بك، وأعتقد أن <لأ href = "http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/ArrayBlockingQueue.html" يختلط = "noreferrer" > ArrayBlockingQueue (أو الأشقاء) قد تكون ذات فائدة. أنها تبدو بعد المزامنة بالنسبة لك، حتى المواضيع يمكن الكتابة إلى قائمة الانتظار أو ملاعبة / اتخاذ دون عمل تزامن إضافي على الجزء الخاص بك.

وهذا صحيح، وتوثيق:

HTTP : //java.sun.com/javase/6/docs/api/java/util/Collections.html#synchronizedList (java.util.List)

ولكن، لمسح القائمة، مجرد دعوة <لأ href = "http://java.sun.com/javase/6/docs/api/java/util/List.html#clear ()" يختلط = " noreferrer "> List.clear () .

نعم هذه هي الطريقة الصحيحة، ولكن مطلوب كتلة متزامنة إذا كنت تريد كل عمليات الإزالة معا لتكون آمنة - ما لم يكن قائمة الانتظار فارغ لا إزالة المسموح بها. تخميني هو أن كنت ترغب فقط في عمليات طابور وdequeue آمنة، حتى تتمكن من إزالة كتلة متزامنة.

ولكن هناك طوابير المتزامنة المتقدمة حتى في جاوة مثل <وأ href = "http://java.sun.com/javase/6/docs/api/java/util/concurrent/ConcurrentLinkedQueue.html" يختلط = "noreferrer"> ConcurrentLinkedQueue

ودعونا نلقي قائمة العادية (تنفذ من قبل الطبقة ArrayList) وجعلها متزامنة. ويظهر ذلك في فئة SynchronizedListExample.     نحن نمر طريقة Collections.synchronizedList على ArrayList جديدة من سلاسل. طريقة إرجاع قائمة متزامنة من سلاسل.     // هنا هو الطبقة SynchronizedArrayList

package com.mnas.technology.automation.utility;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import org.apache.log4j.Logger;
/**
* 
* @author manoj.kumar
* @email kumarmanoj.mtech@gmail.com
* 
*/
public class SynchronizedArrayList {
    static Logger log = Logger.getLogger(SynchronizedArrayList.class.getName());
    public static void main(String[] args) {    
        List<String> synchronizedList = Collections.synchronizedList(new ArrayList<String>());
        synchronizedList.add("Aditya");
        synchronizedList.add("Siddharth");
        synchronizedList.add("Manoj");
        // when iterating over a synchronized list, we need to synchronize access to the synchronized list
        synchronized (synchronizedList) {
            Iterator<String> iterator = synchronizedList.iterator();
            while (iterator.hasNext()) {
                log.info("Synchronized Array List Items: " + iterator.next());
            }
        }    
    }
}

لاحظ أنه عندما بالتكرار عبر القائمة، هذا الوصول لا يزال يتم استخدام كتلة متزامنة ان اقفال على الكائن synchronizedList. بشكل عام، بالتكرار عبر مجموعة متزامنة ينبغي أن يتم في كتلة متزامنة

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top