الفريق العربي للبرمجةأرشيف المنتديات · 2000 – 2023
نسخة أرشيفية للقراءة فقط — التسجيل والمشاركة مغلقان، والمحتوى محفوظ كما كان.

استفسار على ConcurrentLinkedQueue

بدأه pro.fahd في 3 سبتمبر 2012 · 4 رد · 722 مشاهدة · في JavaSE
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

وجدت هذا المثال يشرح ConcurrentLinkedQueue

ولدي كم سؤال في المثال اود توضيحه

 */
public class Producer implements Runnable {

    private static int ctr;
    private final Queue<Message> messageQueue;
    private final Random r;

    public Producer(Queue<Message> messageQueue) {
        this.messageQueue = messageQueue;
        r = new Random();
    }

    @Override
    public void run() {
        while (true) {
            produce();
            int wait = r.nextInt(5000);
            try {
                Thread.sleep(wait);
            } catch (InterruptedException ex) {
                Logger.getLogger(Producer.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }

لماذا وضع synchronized داخل method لكي لا يمنع method كامله .. صحيح؟

private void produce() {
        Message m = new Message(++ctr, "Example message.");
        messageQueue.offer(m);
        synchronized (messageQueue) {
            messageQueue.notifyAll();
        }
        System.out.println("Producer: " + m);
    }

طيب السطر التالي سوف يكون فيه damaged لأن يسمح لthread اخر بتغير القيمه صحيح ..؟

messageQueue.offer(m);

________________________________________________

تم تعديل هذه المشاركة بواسطة pro.fahd في 3 سبتمبر 2012 في 11:34

albert_einstein.jpg

Untitled-AE.jpg
#2

منذ جافا 5 توجد الutil.concurrent والتي احتوت على الكثير من الHigh level classes التي يفرض ان نستخدمها بدلاً من الطرق القديمة وخصوصاً في الLocking/Notifications .

حالياً هناك نوعين من الQueue ، الأول يقوم بعمل Blocking للget method اذا كان الQueue فارغ ، ايضاً يقوم بعمل block في حالة كان الصف ممتئلي (هذا فقط للصفوف المحددة بحجم معين Bounded Queue) ، النوع الثاني وهو Non-Blocking وهو ان اي طلب حصول offer على القيمة تكون مباشره واذا لم يجد ستكون القيمة NULL.

الذي تقوم به حالياً هو اختيار غير جيد لنوع الQueue والسبب أنك تريد الصف ان يكون BlockingQueue (وليكن نوعه هو LinkedBlockingQueue) بدلاً من الNon-Blocking (الذي استخدمته ConcurrentLinkedQueue).

على كل حال هذه الكلاسات Concurrent Collections تعتبر Thread-Safe بمعنى لن تحتاج الى Synchronization بعد الآن لأي من ال Atomic Operations (مثلاً ادخال قيمة أو سحب قيمة)..

حالياً سبب وجود Synchronization هو في عمليات الWaiting/Notify لأنك عندما تريد ان تنادي بقية الThreads المنتظرة ، أو أن تضع الثريد في حالة الانتظار يجب أن تضمن أن هذا الكائن فيه ثريد واحد فقط في هذه اللحظه.. فالSynchornization هنا مطلوب لهذه العمليات..

لكن لو استخدمت الBlockingQueue سوف تريح نفسك تماماً وتنسى كل الwait/notify/notiyAll/sleep وتتعامل مع دالتين فقط:

queue.take();
queue.put(object);

طبعاً هناك أنواع من الBlocking Queue ولكنها تكون على حسب ما تريد ، مثلاً اذا كنت تريد صف بحجم ثابت Bounded Queue فاستخدم ArrayBlockingQueue ، وهكذا كل نوع لديه وقت مناسب للاستخدام..

شاهد المثال:

http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/BlockingQueue.html

بالتوفيق،

1

http://informatic-ar.com منصة تعليمية عربية في علوم الحاسب والبرمجة

https://moalfat.com  للكتب الالكترونية والكورسات التعليمية

Everything we see now is just an engineering solution based on old science

#3
Wajdy Essam كتب:

منذ جافا 5 توجد الutil.concurrent والتي احتوت على الكثير من الHigh level classes التي يفرض ان نستخدمها بدلاً من الطرق القديمة وخصوصاً في الLocking/Notifications .

حالياً هناك نوعين من الQueue ، الأول يقوم بعمل Blocking للget method اذا كان الQueue فارغ ، ايضاً يقوم بعمل block في حالة كان الصف ممتئلي (هذا فقط للصفوف المحددة بحجم معين Bounded Queue) ، النوع الثاني وهو Non-Blocking وهو ان اي طلب حصول offer على القيمة تكون مباشره واذا لم يجد ستكون القيمة NULL.

الذي تقوم به حالياً هو اختيار غير جيد لنوع الQueue والسبب أنك تريد الصف ان يكون BlockingQueue (وليكن نوعه هو LinkedBlockingQueue) بدلاً من الNon-Blocking (الذي استخدمته ConcurrentLinkedQueue).

على كل حال هذه الكلاسات Concurrent Collections تعتبر Thread-Safe بمعنى لن تحتاج الى Synchronization بعد الآن لأي من ال Atomic Operations (مثلاً ادخال قيمة أو سحب قيمة)..

حالياً سبب وجود Synchronization هو في عمليات الWaiting/Notify لأنك عندما تريد ان تنادي بقية الThreads المنتظرة ، أو أن تضع الثريد في حالة الانتظار يجب أن تضمن أن هذا الكائن فيه ثريد واحد فقط في هذه اللحظه.. فالSynchornization هنا مطلوب لهذه العمليات..

لكن لو استخدمت الBlockingQueue سوف تريح نفسك تماماً وتنسى كل الwait/notify/notiyAll/sleep وتتعامل مع دالتين فقط:

queue.take();
queue.put(object);

طبعاً هناك أنواع من الBlocking Queue ولكنها تكون على حسب ما تريد ، مثلاً اذا كنت تريد صف بحجم ثابت Bounded Queue فاستخدم ArrayBlockingQueue ، وهكذا كل نوع لديه وقت مناسب للاستخدام..

شاهد المثال:

http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/BlockingQueue.html

بالتوفيق،

شكرا اخي وجدي

لقد اطلعت على الرابط

لكن عندي سوال

اذا عندي multi-thread

و مشترك بينهم ال queu

واضاف احدهم قيمه

كيفيه اخبار باقي ال threads انه تم اضافه قيمه اخرى

لا يوجد notfiy كما قلت

وال take و put لا تخبر بقيه threads

 	put(E e)
Inserts the specified element into this queue, waiting if necessary for space to become available.

take()
Retrieves and removes the head of this queue, waiting if necessary until an element becomes available.

تم تعديل هذه المشاركة بواسطة pro.fahd في 3 سبتمبر 2012 في 22:54

albert_einstein.jpg

Untitled-AE.jpg
#4

اذا وضعتها داخل حلقة while true ، سوف تكون في حالة طلب دائم، وعندما تقوم بعمل take ولم يكن هناك داتا فسوف يكون الثريد في حالة الانتظار، وداخلياً سوف يتم عمل كمال عمله عندما يتم ادخال اي بيانات بواسطة ثريد اخر.. (اي لن يرجع لبدايه الحلفة الا في حالة وجد داتا وقام بأخذها، سوف يعود للحلقة ومره اخرى سوف يرجع للانتظار الى حين وجود داتا).

http://informatic-ar.com منصة تعليمية عربية في علوم الحاسب والبرمجة

https://moalfat.com  للكتب الالكترونية والكورسات التعليمية

Everything we see now is just an engineering solution based on old science

#5
Wajdy Essam كتب:

اذا وضعتها داخل حلقة while true ، سوف تكون في حالة طلب دائم، وعندما تقوم بعمل take ولم يكن هناك داتا فسوف يكون الثريد في حالة الانتظار، وداخلياً سوف يتم عمل كمال عمله عندما يتم ادخال اي بيانات بواسطة ثريد اخر.. (اي لن يرجع لبدايه الحلفة الا في حالة وجد داتا وقام بأخذها، سوف يعود للحلقة ومره اخرى سوف يرجع للانتظار الى حين وجود داتا).

اها فهمت

شكرا اخي وجدي

albert_einstein.jpg

Untitled-AE.jpg

مواضيع مشابهة