لمحة جافاوية 56: كرر لكل عنصر في ضوء تعدد الخيوط

السلام عليكم

يقول المتنبي
كفى بك داءاً أن ترى الموت شافياً
وحسب المنايا أن يكن أمانياً

المعنى أن أسوأ الداء هو الداء الذي يتمنى صاحبه الموت
وأسوأ أنواع الحياة الحياة التي يتمنى صاحبها الموت
لماذا أذكر هذه الأبيات لكم؟
ما من سبب يذكر
كل ما هناك أني أعجبت بهذا البيت
فقررت أن أضعه بين أيديكم

على كل دعونا من هذا ولأكلمكم عن لمحة اليوم
اطلعوا على الشيفرتين التاليتين وأخبروني هل هناك فرق

Vector integers = new Vector();
for (Integer i : integers) {
	System.out.println(i);
}
Vector integers = new Vector();
for (int j = 0; j < integers.size(); j++) {
	System.out.println(j);
}

طبعاً من النظرة الأولى يتضح لي أننا قمنا بطباعة العناصر الموجودة في الكائن integers
على كل هذا جميل جداً
جربوا الشيفرتين وأخبروني هل حصلتم على نفس النتيجة
(صحيح نفس النتيجة لا أحب أسلوب الحواة هذا هات ما عندك وارحمنا)
ممممممممممممممممممممممم
بالطبع ستحصلوا على نفس النتيجة
لكنكم لم تسألوا أنفسكم لماذا استخدمت كائن من نوع Vector
وأنا لا أنفك عن تذكيركم بأن Vector مكلفة جداً
بالطبع أنا أريدكم أن تجربوا الشيفرتين السابقتين في وجود تعدد خيوط Multithreading
(هذا أمر صعب جداً ما رأيك أن تضع الشيفرة كاملة)
أعتقد أني علمتكم الكثير من الأمور
لذا لا أعتقد أن هذا الأمر صعب عليكم
(إما أن تعطينا الشيفرة أو سأعمل(بفتح السين وضم الألف وتسكين العين) في رقبتك شفرة حلاقة حافية)
اعععععع
لا يا عم عبده إلا زعلك
هذه الشيفرة ضعوا فيها الشيفرتين السابقتين وهاتوا ملاحظاتكم

package iter;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Vector;

public class Test {
	Vector integers = new Vector();
	
	public Test() {
		// integers=Collections.synchronizedList(integers);
		int i = 0;
		while (i < 1000) {
			integers.add(i++);
		}
		Thread iterate = new Thread(new Runnable() {

			public void run() {
				//هنا ضعوا الشيفرتين السابقتين بدون أول سطر
			}
		});
		iterate.start();
		System.out.println(integers.size());
		Thread iterate2 = new Thread(new Runnable() {

			public void run() {
				while (i < 100) {
					integers.add(20);
					i++;
					System.out.println("th2");
				}

			}
		});
		iterate2.start();
	}

	public static void main(String[] args) {
		new Test();
	}
}

في الشيفرة code السابقة استخدمت خيطين
الخيط thread الأول يقوم بطباعة عناصر المتجه vector
والخيط thread الثاني يضيف على المتجه vector
(استخدمت التكرار loop في الخيط الثاني لضمان أن يحصل عملية إضافة وعملية طلب على المتجه في نفس الوقت)
ماذا تلاحظون عند وضع الشيفرتين في الشيفرة السابقة
الشيفرة الأولى تعطي خطأً اسمه java.util.ConcurrentModificationException
الشيفرة الثانية تعمل بشكل جيد
وهذا يعني أن الشيفرة الأولى غير آمنة في تعدد الخيوط Thread unsafe
إلى هنا يمكننا أن نقول أن اللمحة الخاصة بنا انتهت
ما سيأتي بعد هذا هو زيادة من عندي للتوضيح لمن أراد أن يعرف أكثر

السبب في كون الشيفرة الأولى أعطت هذا الخطأ
أن foreach تعتمد على Iterator في التعامل مع العناصر
والتعامل مع الفئة Iterator لا يكون مأمون العواقب إلا لو تم كله مرة واحدة
بمعنى يجب أن تكون الشيفرة كالتالي

Vector integers = new Vector();
synchronized(integers){
	for (Integer i : integers) {
		System.out.println(i);
	}
}

طبعاً هذه عملية مكلفة جداً وغير مجدية بالنسبة لنا
على كل ربما يحتاج لها أحد لسبب لا أعلمه

استنتاج ذكي:
ليس كل جديد جيد دائماً
(من قال أن التكرار لكل عنصر foreach جديد يا حيوان)
لا أعرف لماذا أنت رقيق في ألفاظك يا أخ عبده
على كل قصدت أنها أحدث من التكرار العادي

كالعادة أي أسئلة أنا في الخدمة

تحياتي

Tags: , , , , , , , , , , ,

2 Responses to “لمحة جافاوية 56: كرر لكل عنصر في ضوء تعدد الخيوط”

  1. abuouf قال:

    في مشكلة في التدوينة دي كل ما ادخل عليها لا اجد كلام !!!!!!!!!!!!

  2. admin قال:

    شكراُ على التنبيه أخ عبدالله

    تم إصلاح المشكلة

Leave a Reply