CodeGym /جاوا بلاگ /Random-SD /گڏو گڏ بهتر: جاوا ۽ ٿريڊ ڪلاس. حصو III - رابطي
John Squirrels
سطح
San Francisco

گڏو گڏ بهتر: جاوا ۽ ٿريڊ ڪلاس. حصو III - رابطي

گروپ ۾ شايع ٿيل
تفصيلن جو هڪ مختصر جائزو ته ڪيئن موضوعن سان تعلق رکن ٿا. اڳي، اسان ڏٺو ته ڪئين سلسلا هڪ ٻئي سان هم وقت ساز ٿين ٿا. هن ڀيري اسان انهن مسئلن تي غور ڪنداسين جيڪي پيدا ٿي سگهن ٿيون جيئن موضوعن جي وچ ۾ لهه وچڙ ۾، ۽ اسان ان بابت ڳالهائينداسين ته انهن کان ڪيئن بچجي. اسان وڌيڪ تفصيلي مطالعي لاءِ ڪجهه مفيد لنڪ پڻ فراهم ڪنداسين. گڏو گڏ بهتر: جاوا ۽ ٿريڊ ڪلاس.  حصو III - رابطي - 1

تعارف

تنهن ڪري، اسان ڄاڻون ٿا ته جاوا موضوع آهن. توھان ان جي باري ۾ پڙھي سگھوٿا جائزي ۾ عنوان سان گڏ بهتر: جاوا ۽ ٿريڊ ڪلاس. حصو I - عملدرآمد جا سلسلا . ۽ اسان ان حقيقت کي دريافت ڪيو ته موضوع هڪ ٻئي سان هم وقت سازي ڪري سگهن ٿا جائزي ۾ هڪ ٻئي سان گڏ بهتر: جاوا ۽ ٿريڊ ڪلاس. حصو II - هم وقت سازي . اهو وقت ڳالهائڻ جو وقت آهي ته موضوع ڪيئن هڪ ٻئي سان لهه وچڙ ۾. اهي حصيداري وسيلن کي ڪيئن حصيداري ڪندا آهن؟ هتي ڪهڙا مسئلا پيدا ٿي سگهن ٿا؟ گڏو گڏ بهتر: جاوا ۽ ٿريڊ ڪلاس.  حصو III - رابطي - 2

تعطل

سڀ کان خوفناڪ مسئلو تعطل آهي. Deadlock اهو آهي جڏهن ٻه يا وڌيڪ سلسلا هميشه لاء ٻئي جي انتظار ۾ آهن. اسان Oracle ويب پيج مان ھڪڙو مثال کڻنداسين جيڪو بيان ڪري ٿو ڊيڊ لاڪ :
public class Deadlock {
    static class Friend {
        private final String name;
        public Friend(String name) {
            this.name = name;
        }
        public String getName() {
            return this.name;
        }
        public synchronized void bow(Friend bower) {
            System.out.format("%s: %s bowed to me!%n",
                    this.name, bower.getName());
            bower.bowBack(this);
        }
        public synchronized void bowBack(Friend bower) {
            System.out.format("%s: %s bowed back to me!%n",
                    this.name, bower.getName());
        }
    }

    public static void main(String[] args) {
        final Friend alphonse = new Friend("Alphonse");
        final Friend gaston = new Friend("Gaston");
        new Thread(() -> alphonse.bow(gaston)).start();
        new Thread(() -> gaston.bow(alphonse)).start();
    }
}
ڊيڊ لاڪ هتي پهريون ڀيرو نه ٿي سگھي، پر جيڪڏهن توهان جو پروگرام هينگ ٿئي ٿو، ته پوءِ اهو وقت آهي هلڻ جو jvisualvm: گڏو گڏ بهتر: جاوا ۽ ٿريڊ ڪلاس.  حصو III - رابطي - 3هڪ JVisualVM پلگ ان انسٽال ٿيل (ذريعي اوزار -> پلگ ان) سان، اسان ڏسي سگهون ٿا ته ڊيڊ لاڪ ڪٿي ٿيو آهي:
"Thread-1" - Thread t@12
   java.lang.Thread.State: BLOCKED
	at Deadlock$Friend.bowBack(Deadlock.java:16)
	- waiting to lock <33a78231> (a Deadlock$Friend) owned by "Thread-0" t@11
ٿريڊ 1 ٿريڊ 0 مان بند ٿيڻ جو انتظار ڪري رهيو آهي. ائين ڇو ٿو ٿئي؟ Thread-1هلڻ شروع ٿئي ٿو ۽ Friend#bowطريقي سان عمل ڪري ٿو. اهو synchronizedلفظ سان نشان لڳايو ويو آهي، جنهن جو مطلب آهي ته اسان مانيٽر حاصل ڪري رهيا آهيون this(موجوده اعتراض). طريقو جو ان پٽ ٻئي Friendاعتراض جو حوالو هو. هاڻي، Thread-1ٻئي تي طريقي سان عمل ڪرڻ چاهي ٿو Friend، ۽ ائين ڪرڻ لاء ان جو تالا حاصل ڪرڻ گهرجي. پر جيڪڏهن ٻيو ڌاڳو (هن صورت ۾ Thread-0) طريقي سان داخل ٿيڻ ۾ ڪامياب ٿي ويو bow()، پوء تالا اڳ ۾ ئي حاصل ڪيو ويو آهي ۽ Thread-1انتظار ڪري ٿو Thread-0، ۽ ان جي برعڪس. اهو تعطل ناقابل حل آهي، ۽ اسان ان کي تعطل سڏيو آهي. موت جي گرفت وانگر جيڪو آزاد نه ٿو ڪري سگهجي، تعطل هڪ باهمي بلاڪ آهي جنهن کي ٽوڙي نٿو سگهجي. Deadlock جي ٻي وضاحت لاءِ، توھان ھي وڊيو ڏسي سگھو ٿا: Deadlock ۽ Livelock وضاحت ڪئي وئي .

چريو

جيڪڏهن اتي تعطل آهي، ته اتي به چرپر آهي؟ ها، اتي آهي :) لائيو لاڪ تڏهن ٿيندو آهي جڏهن ڌاڙا ٻاهران زنده نظر اچن ٿا، پر اهي ڪجهه به ڪرڻ جي قابل نه هوندا آهن، ڇاڪاڻ ته انهن لاءِ ڪم جاري رکڻ لاءِ جيڪي شرط گهربل هوندا آهن، اهي پورا نه ٿي سگهندا آهن. بنيادي طور تي، لائيو لاڪ ڊيڊ لاڪ سان ملندڙ جلندڙ آهي، پر موضوع هڪ مانيٽر جي انتظار ۾ "هنگ" نٿا ڪن. ان جي بدران، اهي هميشه لاء ڪجهه ڪري رهيا آهن. مثال طور:
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class App {
    public static final String ANSI_BLUE = "\u001B[34m";
    public static final String ANSI_PURPLE = "\u001B[35m";

    public static void log(String text) {
        String name = Thread.currentThread().getName(); // Like "Thread-1" or "Thread-0"
        String color = ANSI_BLUE;
        int val = Integer.valueOf(name.substring(name.lastIndexOf("-") + 1)) + 1;
        if (val != 0) {
            color = ANSI_PURPLE;
        }
        System.out.println(color + name + ": " + text + color);
        try {
            System.out.println(color + name + ": wait for " + val + " sec" + color);
            Thread.currentThread().sleep(val * 1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        Lock first = new ReentrantLock();
        Lock second = new ReentrantLock();

        Runnable locker = () -> {
            boolean firstLocked = false;
            boolean secondLocked = false;
            try {
                while (!firstLocked || !secondLocked) {
                    firstLocked = first.tryLock(100, TimeUnit.MILLISECONDS);
                    log("First Locked: " + firstLocked);
                    secondLocked = second.tryLock(100, TimeUnit.MILLISECONDS);
                    log("Second Locked: " + secondLocked);
                }
                first.unlock();
                second.unlock();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        };

        new Thread(locker).start();
        new Thread(locker).start();
    }
}
هن ڪوڊ جي ڪاميابي ان ترتيب تي منحصر آهي جنهن ۾ جاوا ٿريڊ شيڊيولر ٿريڊز کي شروع ڪري ٿو. جيڪڏهن Thead-1پهرين شروع ٿئي ٿي، ته پوءِ اسان لائيو لاڪ حاصل ڪريون ٿا:
Thread-1: First Locked: true
Thread-1: wait for 2 sec
Thread-0: First Locked: false
Thread-0: wait for 1 sec
Thread-0: Second Locked: true
Thread-0: wait for 1 sec
Thread-1: Second Locked: false
Thread-1: wait for 2 sec
Thread-0: First Locked: false
Thread-0: wait for 1 sec
...
جئين توهان مثال مان ڏسي سگهو ٿا، ٻنهي موضوعن کي موڙ ۾ ٻنهي تالا حاصل ڪرڻ جي ڪوشش ڪئي، پر اهي ناڪام ٿيا. پر، اهي تعطل ۾ نه آهن. ٻاهران، سڀ ڪجهه ٺيڪ آهي ۽ اهي پنهنجو ڪم ڪري رهيا آهن. گڏو گڏ بهتر: جاوا ۽ ٿريڊ ڪلاس.  حصو III - رابطي - 4JVisualVM جي مطابق، اسان ننڊ جا دور ۽ پارڪ جو دور ڏسون ٿا (اهو اهو آهي جڏهن هڪ ڌاڳو هڪ تالا حاصل ڪرڻ جي ڪوشش ڪري ٿو - اهو پارڪ اسٽيٽ ۾ داخل ٿئي ٿو، جيئن اسان اڳ ۾ بحث ڪيو جڏهن اسان موضوع جي هم وقت سازي بابت ڳالهايو ) . توھان ھتي لائيو لاڪ جو ھڪڙو مثال ڏسي سگھو ٿا: Java - Thread Livelock .

بُک

تعطل ۽ لائيو لاڪ کان علاوه، هڪ ٻيو مسئلو آهي جيڪو ملٽي ٿريڊنگ دوران ٿي سگهي ٿو: بکيو. اهو رجحان بلاڪ ڪرڻ جي پوئين شڪلن کان مختلف آهي جنهن ۾ موضوعن کي بلاڪ نه ڪيو ويو آهي - انهن وٽ صرف ڪافي وسيلا نه آهن. نتيجي طور، جڏهن ته ڪجهه موضوعن تي عمل ڪرڻ جو وقت وٺندو آهي، ٻيا هلائڻ جي قابل نه هوندا آهن: گڏو گڏ بهتر: جاوا ۽ ٿريڊ ڪلاس.  حصو III - رابطي - 5

https://www.logicbig.com/

توهان هتي هڪ بهترين مثال ڏسي سگهو ٿا: Java - Thread Starvation and Fairness . هي مثال ڏيکاري ٿو ته ٿريڊن سان ڇا ٿئي ٿو بک جي دوران ۽ ڪيئن هڪ ننڍڙي تبديلي توهان کي لوڊ کي برابر طور تي ورهائڻ جي اجازت ڏئي ٿي Thread.sleep().Thread.wait()گڏو گڏ بهتر: جاوا ۽ ٿريڊ ڪلاس.  حصو III - رابطي - 6

نسل جون حالتون

multithreading ۾، اتي هڪ "نسل حالت" جي طور تي هڪ شيء آهي. اهو رجحان تڏهن ٿئي ٿو جڏهن ٿريڊز هڪ وسيلو شيئر ڪن ٿا، پر ڪوڊ اهڙي طريقي سان لکيو ويو آهي ته جيئن اهو صحيح شيئرنگ کي يقيني نه بڻائي. هڪ مثال ڏسو:
public class App {
    public static int value = 0;

    public static void main(String[] args) {
        Runnable task = () -> {
            for (int i = 0; i < 10000; i++) {
                int oldValue = value;
                int newValue = ++value;
                if (oldValue + 1 != newValue) {
                    throw new IllegalStateException(oldValue + " + 1 = " + newValue);
                }
            }
        };
        new Thread(task).start();
        new Thread(task).start();
        new Thread(task).start();
    }
}
هي ڪوڊ شايد پهريون ڀيرو غلطي پيدا نه ڪري سگھي. جڏهن اهو ٿئي ٿو، اهو شايد هن طرح نظر اچي ٿو:
Exception in thread "Thread-1" java.lang.IllegalStateException: 7899 + 1 = 7901
	at App.lambda$main$0(App.java:13)
	at java.lang.Thread.run(Thread.java:745)
جئين توهان ڏسي سگهو ٿا، ڪجهه غلط ٿي ويو جڏهن newValueهڪ قيمت مقرر ڪئي وئي هئي. newValueتمام وڏو آهي. valueنسل جي حالت جي ڪري، ھڪڙي سلسلي کي ٻن بيانن جي وچ ۾ متغير کي تبديل ڪرڻ ۾ مدد ڪئي . اهو معلوم ٿئي ٿو ته سلسلي جي وچ ۾ هڪ نسل آهي. هاڻي سوچيو ته اهو ڪيترو ضروري آهي ته مانيٽري ٽرانزيڪشن سان اهڙيون غلطيون نه ڪيون وڃن... مثال ۽ ڊراگرام پڻ هتي ڏسي سگهجن ٿا: جاوا سلسلي ۾ نسل جي حالت کي ترتيب ڏيڻ لاءِ ڪوڊ .

اُٿلندڙ

موضوعن جي رابطي جي باري ۾ ڳالهائيندي، volatileلفظ قابل ذڪر آهي. اچو ته هڪ سادي مثال ڏسو:
public class App {
    public static boolean flag = false;

    public static void main(String[] args) throws InterruptedException {
        Runnable whileFlagFalse = () -> {
            while(!flag) {
            }
            System.out.println("Flag is now TRUE");
        };

        new Thread(whileFlagFalse).start();
        Thread.sleep(1000);
        flag = true;
    }
}
سڀ کان وڌيڪ دلچسپ، اهو تمام گهڻو ڪم نه ڪرڻ جو امڪان آهي. نئون ٿريڊ فيلڊ ۾ تبديلي نه ڏسندو flag. فيلڊ لاءِ ھن کي درست ڪرڻ لاءِ flag، اسان کي لفظ استعمال ڪرڻ گھرجي volatile. ڪيئن ۽ ڇو؟ پروسيسر سڀني عملن کي انجام ڏئي ٿو. پر حسابن جا نتيجا ضرور محفوظ ڪيا وڃن. ان لاءِ مکيه ياداشت آهي ۽ پروسيسر جي ڪيش آهي. پروسيسر جا ڪيش ميموري جي هڪ ننڍڙي حصي وانگر هوندا آهن جيڪي ڊيٽا تائين رسائي حاصل ڪرڻ لاءِ استعمال ڪيا ويندا آهن جڏهن ته مکيه ميموري تائين رسائي حاصل ڪرڻ کان وڌيڪ جلدي. پر هر شيءِ جو هڪ پاسو آهي: ڪيش ۾ ڊيٽا اپڊيٽ نه ٿي سگھي (جيئن مٿي ڏنل مثال ۾، جڏهن پرچم فيلڊ جي قيمت اپڊيٽ نه ڪئي وئي هئي). تنهن ڪري، volatileلفظ JVM کي ٻڌائي ٿو ته اسان اسان جي متغير کي ڪيش ڪرڻ نٿا چاهيون. هي اجازت ڏئي ٿو ته تازه ترين نتيجا سڀني موضوعن تي ڏسڻ لاءِ. هي هڪ انتهائي آسان وضاحت آهي. جيئن ته volatileلفظي لفظ لاء، مان تمام گهڻو سفارش ڪريان ٿو ته توهان هي مضمون پڙهو . وڌيڪ معلومات لاءِ، مان توهان کي جاوا ميموري ماڊل ۽ Java Volatile Keyword پڙهڻ جي پڻ صلاح ڏيان ٿو . اضافي طور تي، اهو ياد رکڻ ضروري آهي ته اهو volatileڏسڻ جي باري ۾ آهي، ۽ تبديلين جي جوهر بابت نه. "ريس حالتون" سيڪشن ۾ ڪوڊ کي ڏسي، اسان IntelliJ IDEA ۾ هڪ ٽول ٽائپ ڏسندا: گڏو گڏ بهتر: جاوا ۽ ٿريڊ ڪلاس.  حصو III - رابطي - 7هي انسپيڪشن IntelliJ IDEA ۾ شامل ڪيو ويو مسئلو IDEA-61117 جي حصي طور، جيڪو 2010 ۾ رليز نوٽس ۾ درج ڪيو ويو .

ايٽمي

ايٽمي آپريشنز اهي آپريشن آهن جن کي ورهائي نٿو سگهجي. مثال طور، متغير کي قيمت تفويض ڪرڻ جو عمل ايٽمي هجڻ گهرجي. بدقسمتي سان، واڌارو آپريشن ايٽمي نه آهي، ڇاڪاڻ ته واڌارو جي ضرورت آهي ٽي سي پي يو آپريشنز: پراڻي قيمت حاصل ڪريو، ان ۾ هڪ شامل ڪريو، پوء قيمت بچايو. ايٽمي اهميت ڇو آهي؟ انڪريمينٽ آپريشن سان، جيڪڏهن ڪا نسل جي حالت آهي، ته پوءِ گڏيل وسيلو (يعني گڏيل قدر) اوچتو ڪنهن به وقت تبديل ٿي سگهي ٿو. اضافي طور تي، آپريشن شامل آهن 64-bit جوڙجڪ، مثال طور long۽ double، ايٽمي نه آهن. وڌيڪ تفصيل هتي پڙهي سگهجن ٿا: 64-bit ويلز پڙهڻ ۽ لکڻ دوران ايٽمي کي يقيني بڻايو . ايٽمي سان لاڳاپيل مسئلا هن مثال ۾ ڏسي سگهجن ٿا:
public class App {
    public static int value = 0;
    public static AtomicInteger atomic = new AtomicInteger(0);

    public static void main(String[] args) throws InterruptedException {
        Runnable task = () -> {
            for (int i = 0; i < 10000; i++) {
                value++;
                atomic.incrementAndGet();
            }
        };
        for (int i = 0; i < 3; i++) {
            new Thread(task).start();
        }
        Thread.sleep(300);
        System.out.println(value);
        System.out.println(atomic.get());
    }
}
خاص AtomicIntegerطبقو هميشه اسان کي 30,000 ڏيندو، پر valueوقت وقت تي تبديل ٿيندو. ھن موضوع جو ھڪڙو مختصر جائزو آھي: جاوا ۾ ايٽمي متغيرن جو تعارف . "مقابلي ۽ ادل بدل" الورورٿم ايٽمي طبقن جي دل تي واقع آهي. توھان ان بابت وڌيڪ پڙھي سگھوٿا ھتي لاڪ فري الگورٿمز جي مقابلي ۾ - CAS ۽ FAA جي مثال تي JDK 7 ۽ 8 يا وڪيپيڊيا تي موازن ۽ ادل جي مضمون ۾. گڏو گڏ بهتر: جاوا ۽ ٿريڊ ڪلاس.  حصو III - رابطي - 9

http://jeremymanson.blogspot.com/2008/11/what-volatile-means-in-java.html

ٿئي ٿو- اڳي

هتي هڪ دلچسپ ۽ پراسرار تصور آهي جنهن کي "اڳ ۾ ٿئي ٿو" سڏيو ويندو آهي. توهان جي موضوعن جي مطالعي جي حصي جي طور تي، توهان کي ان بابت پڙهڻ گهرجي. واقعن کان اڳ جو تعلق اهو حڪم ڏيکاري ٿو جنهن ۾ سلسلي جي وچ ۾ عمل ڏٺو ويندو. ڪيتريون ئي تفسير ۽ تبصرا آهن. هتي هن موضوع تي سڀ کان تازي پيش ڪيل پيشين مان هڪ آهي: جاوا "هپين-کان اڳ" تعلقات .

خلاصو

هن جائزي ۾، اسان ڪجهه تفصيلن جي ڳولا ڪئي آهي ته ڪئين موضوع ڪيئن لهه وچڙ ڪن ٿا. اسان انهن مسئلن تي بحث ڪيو جيڪي پيدا ٿي سگهن ٿا، انهي سان گڏ انهن کي سڃاڻڻ ۽ ختم ڪرڻ جا طريقا. موضوع تي اضافي مواد جي فهرست: گڏو گڏ بهتر: جاوا ۽ ٿريڊ ڪلاس. حصو I - عملدرآمد جا موضوع گڏ ڪري بهتر: جاوا ۽ ٿريڊ ڪلاس. حصو II - هم وقت سازي بهتر گڏجي: جاوا ۽ ٿريڊ ڪلاس. حصو IV — سڏڻ لائق، مستقبل، ۽ دوست گڏ ڪري بهتر: جاوا ۽ ٿريڊ ڪلاس. حصو V - ايگزيڪيوٽر، ٿريڊ پول، فورڪ / شامل ٿيڻ بهتر گڏجي: جاوا ۽ ٿريڊ ڪلاس. حصو VI - فائر پري!
تبصرا
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION