জাভা মাল্টিথ্রেডিংয়ে কীভাবে কাউন্টডাউনল্যাচ ব্যবহার করা হয়?


183

কেউ জাভা CountDownLatchকী এবং কখন এটি ব্যবহার করবেন তা বুঝতে আমাকে সহায়তা করতে পারে?

এই প্রোগ্রামটি কীভাবে কাজ করে সে সম্পর্কে আমার খুব পরিষ্কার ধারণা নেই। আমি বুঝতে পারি যে তিনটি থ্রেড একবারে শুরু হবে এবং প্রতিটি থ্রেড 3000 মিমি পরে কাউন্টডাউনল্যাচকে কল করবে। সুতরাং গণনা এক এক করে হ্রাস পাবে। ল্যাচ শূন্য হওয়ার পরে প্রোগ্রামটি "সম্পূর্ণ" প্রিন্ট করে। আমি যেভাবে বুঝতে পেরেছি তা ভুল।

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

class Processor implements Runnable {
    private CountDownLatch latch;

    public Processor(CountDownLatch latch) {
        this.latch = latch;
    }

    public void run() {
        System.out.println("Started.");

        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        latch.countDown();
    }
}

// ------------------------------------------------ -----

public class App {

    public static void main(String[] args) {

        CountDownLatch latch = new CountDownLatch(3); // coundown from 3 to 0

        ExecutorService executor = Executors.newFixedThreadPool(3); // 3 Threads in pool

        for(int i=0; i < 3; i++) {
            executor.submit(new Processor(latch)); // ref to latch. each time call new Processes latch will count down by 1
        }

        try {
            latch.await();  // wait until latch counted down to 0
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println("Completed.");
    }

}


8
আমি মাত্র একটি অ্যান্ড্রয়েড সমান্তরাল পরিষেবা ব্যাচের জন্য আপনার প্রশ্নের নমুনা কোড ব্যবহার করেছি এবং এটি একটি কবজির মতো কাজ করেছে। তোমাকে অনেক ধন্যবাদ!
রাইসগোয়েন

২০১২ সাল থেকে এই ভিডিওটি এখানে পেয়েছে , যা এখানে প্রদর্শিত উদাহরণের সাথে উল্লেখযোগ্য সাদৃশ্য দেখায় । আগ্রহীদের জন্য, এটি জন নামে একটি লোকের জাভা মাল্টি-থ্রেডিং টিউটোরিয়াল সিরিজের অংশ। আমি জন পছন্দ করি অত্যন্ত বাঞ্ছনীয়.
এলিয়া গ্রেডি

উত্তর:


194

হ্যাঁ, আপনি সঠিকভাবে বুঝতে পেরেছিলেন। CountDownLatchল্যাচ নীতিতে কাজ করে, গেটটি খোলা না হওয়া পর্যন্ত মূল থ্রেড অপেক্ষা করবে। একটি থ্রেড এন থ্রেডগুলির জন্য অপেক্ষা করে , এটি তৈরি করার সময় নির্দিষ্ট করা হয়েছে CountDownLatch

যে কোনও থ্রেড, সাধারণত অ্যাপ্লিকেশনের মূল থ্রেড, যা কলটি CountDownLatch.await()গণনা শূন্যে না পৌঁছানো বা অন্য থ্রেড দ্বারা বাধাগ্রস্থ হওয়া পর্যন্ত অপেক্ষা করবে। অন্য সমস্ত থ্রেডগুলি সম্পূর্ণ হয়ে CountDownLatch.countDown()গেলে বা প্রস্তুত হয়ে গেলে কল করে গুনতে হবে ।

গণনা শূন্যে পৌঁছানোর সাথে সাথে অপেক্ষার থ্রেডটি চলতে থাকে। এর অন্যতম অসুবিধা / সুবিধা CountDownLatchহ'ল এটি পুনরায় ব্যবহারযোগ্য নয়: একবার গণনা শূন্যে পৌঁছে গেলে আপনি আর ব্যবহার করতে পারবেন না CountDownLatch

সম্পাদনা:

CountDownLatchপ্রক্রিয়া চালিয়ে যাওয়ার আগে কোনও থ্রেডের (মূল থ্রেডের মতো) এক বা একাধিক থ্রেড সম্পূর্ণ হওয়ার অপেক্ষা করতে হবে যখন ব্যবহার করুন ।

CountDownLatchজাভা ব্যবহারের একটি শাস্ত্রীয় উদাহরণ হ'ল সার্ভার সাইড কোর জাভা অ্যাপ্লিকেশন যা পরিষেবাদি আর্কিটেকচার ব্যবহার করে যেখানে একাধিক পরিষেবা একাধিক থ্রেড দ্বারা সরবরাহ করা হয় এবং সমস্ত পরিষেবা সফলভাবে শুরু না হওয়া পর্যন্ত অ্যাপ্লিকেশন প্রক্রিয়া শুরু করতে পারে না।

পিএস ওপির প্রশ্নের বেশ সহজ সরল উদাহরণ রয়েছে তাই আমি এর একটিও অন্তর্ভুক্ত করি নি।


1
উত্তর দেওয়ার জন্য আপনাকে ধন্যবাদ. আপনি আমাকে একটি উদাহরণ দিতে পারেন যেখানে কাউন্টডাউন ল্যাচ প্রয়োগ করতে হবে?
অমল

11
কাউন্টডাউনল্যাচ কীভাবে ব্যবহার করবেন তার একটি টিউটোরিয়াল এখানে রয়েছে howtodoinjava.com/2013/07/18/…
thiagoh

1
@ নিকোলাবি কিন্তু এই প্রদত্ত উদাহরণে আমরা যোগদানের পদ্ধতি ব্যবহার করে একই ফলাফল অর্জন করতে পারি তাই না?
বিকাশ ভার্মা

3
আমি অ-পুনঃব্যবহারযোগ্যতাটিকে একটি সুবিধা হিসাবে বিবেচনা করব: আপনি নিশ্চিত যে কেউ এটিকে পুনরায় সেট করতে বা গণনা বাড়াতে পারবেন না।
ataulm

3
সুন্দর ব্যাখ্যা। তবে আমি এই বিষয়টিতে কিছুটা দ্বিমত পোষণ করব One thread waits for n number of threads specified while creating CountDownLatch in Java। আপনার যদি এ জাতীয় প্রক্রিয়া দরকার হয় তবে এটি ব্যবহার করা বুদ্ধিমান CyclicBarrier। এই দুই এর মধ্যে মৌলিক ধারণাগত পার্থক্য, যেমন দেওয়া Java concurrency in Practiceহল: Latches are for waiting for events; barriers are for waiting for other threadscyclicBarrier.await()একটি অবরুদ্ধ অবস্থায় যায়।
রাহুল দেব মিশ্র

43

CountDownLatchজাভাতে এক ধরণের সিঙ্ক্রোনাইজার যা এটি প্রক্রিয়া শুরু করার আগে Thread এক বা একাধিক অপেক্ষা করার অনুমতি দেয় Thread

CountDownLatchল্যাচ নীতিতে কাজ করে, গেটটি খোলা না হওয়া পর্যন্ত থ্রেড অপেক্ষা করবে। একটি থ্রেড nতৈরি করার সময় নির্দিষ্ট থ্রেডের জন্য অপেক্ষা করে CountDownLatch

যেমন final CountDownLatch latch = new CountDownLatch(3);

এখানে আমরা কাউন্টারে সেট করেছিলাম 3।

যে কোনও থ্রেড, সাধারণত অ্যাপ্লিকেশনের মূল থ্রেড, যা কলগুলি CountDownLatch.await()গণনা শূন্যে না পৌঁছা পর্যন্ত অপেক্ষা করে বা এটির দ্বারা বাধা হয়ে থাকে Thread। অন্য সমস্ত থ্রেডগুলি সম্পূর্ণ হয়ে CountDownLatch.countDown()গেলে বা কাজের জন্য প্রস্তুত হয়ে কল করার মাধ্যমে গণনা করতে হবে । গণনা শূন্যে পৌঁছানোর সাথে সাথে Threadঅপেক্ষারত চলতে শুরু করে।

এখানে গণনাটি CountDownLatch.countDown()পদ্ধতি অনুসারে হ্রাস পাচ্ছে ।

Threadযা কল await()পদ্ধতি শুন্যতে প্রাথমিক গণনা পৌছানোর পর্যন্ত অপেক্ষা করতে হবে।

শূন্য গণনা করতে অন্যান্য থ্রেডগুলিকে countDown()পদ্ধতিটি কল করতে হবে । গণনাটি শূন্য হয়ে যাওয়ার পরে await()পদ্ধতিটি চালিত করে থ্রেডটি আবার শুরু হবে (এর কার্যকরকরণ শুরু করুন)।

এর অসুবিধা CountDownLatchহ'ল এটি পুনরায় ব্যবহারযোগ্য নয়: একবার গণনা শূন্য হয়ে গেলে এটি আর ব্যবহারযোগ্য হয় না।


new CountDownLatch(3)আমরা newFixedThreadPool সংজ্ঞায়িত থেকে 3 টি থ্রেড হিসাবে ব্যবহার করি ?
চাকলাদার আসফাক আরেফে

প্রসেসিং চালিয়ে যাওয়ার আগে "হওয়া" প্রক্রিয়াজাতকরণ শুরু করার আগে "হওয়া উচিত নয়"?
মারিয়া ইনেস পরনসারি

@ আফেরেফ হ্যাঁ, এটি আপনার কোডের ব্লকটি দিয়ে যাওয়া থ্রেডের সংখ্যা
বিশাল আকালকোট

23

নিকোলাবি এটি খুব ভালভাবে ব্যাখ্যা করেছে, তবে উদাহরণটি বুঝতে সাহায্য করবে, সুতরাং এখানে একটি সহজ উদাহরণ দেওয়া হল ...

 import java.util.concurrent.*;


  public class CountDownLatchExample {

  public static class ProcessThread implements Runnable {

    CountDownLatch latch;
    long workDuration;
    String name;

    public ProcessThread(String name, CountDownLatch latch, long duration){
        this.name= name;
        this.latch = latch;
        this.workDuration = duration;
    }


    public void run() {
        try {
            System.out.println(name +" Processing Something for "+ workDuration/1000 + " Seconds");
            Thread.sleep(workDuration);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(name+ "completed its works");
        //when task finished.. count down the latch count...

        // basically this is same as calling lock object notify(), and object here is latch
        latch.countDown();
    }
}


public static void main(String[] args) {
    // Parent thread creating a latch object
    CountDownLatch latch = new CountDownLatch(3);

    new Thread(new ProcessThread("Worker1",latch, 2000)).start(); // time in millis.. 2 secs
    new Thread(new ProcessThread("Worker2",latch, 6000)).start();//6 secs
    new Thread(new ProcessThread("Worker3",latch, 4000)).start();//4 secs


    System.out.println("waiting for Children processes to complete....");
    try {
        //current thread will get notified if all chidren's are done 
        // and thread will resume from wait() mode.
        latch.await();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }

    System.out.println("All Process Completed....");

    System.out.println("Parent Thread Resuming work....");



     }
  }

22

যখন আমরা একাধিক থ্রেডের কাজ শেষ করতে অপেক্ষা করতে চাই তখন এটি ব্যবহার করা হয়। এটি থ্রেডে যোগ দেওয়ার অনুরূপ।

যেখানে আমরা কাউন্টডাউনল্যাচ ব্যবহার করতে পারি

একটি দৃশ্যের কথা বিবেচনা করুন যেখানে আমাদের প্রয়োজনীয়তা রয়েছে যেখানে আমাদের তিনটি থ্রেড "এ", "বি" এবং "সি" রয়েছে এবং আমরা "সি" থ্রেডটি কেবল তখনই শুরু করতে চাই যখন "এ" এবং "বি" থ্রেডগুলি তাদের কাজটি সম্পূর্ণ বা আংশিকভাবে সম্পূর্ণ করে।

এটি বাস্তব বিশ্বের আইটি দৃশ্যে প্রয়োগ করা যেতে পারে

এমন দৃশ্যের বিষয়টি বিবেচনা করুন যেখানে ম্যানেজার বিকাশকারী দলের (এ এবং বি) মধ্যে মডিউল বিভক্ত করে এবং যখন উভয় দলই তাদের কাজটি সম্পন্ন করে তখন তিনি এটি পরীক্ষার জন্য কিউএ দলকে নির্ধারণ করতে চান।

public class Manager {
    public static void main(String[] args) throws InterruptedException {
        CountDownLatch countDownLatch = new CountDownLatch(2);
        MyDevTeam teamDevA = new MyDevTeam(countDownLatch, "devA");
        MyDevTeam teamDevB = new MyDevTeam(countDownLatch, "devB");
        teamDevA.start();
        teamDevB.start();
        countDownLatch.await();
        MyQATeam qa = new MyQATeam();
        qa.start();
    }   
}

class MyDevTeam extends Thread {   
    CountDownLatch countDownLatch;
    public MyDevTeam (CountDownLatch countDownLatch, String name) {
        super(name);
        this.countDownLatch = countDownLatch;       
    }   
    @Override
    public void run() {
        System.out.println("Task assigned to development team " + Thread.currentThread().getName());
        try {
                Thread.sleep(2000);
        } catch (InterruptedException ex) {
                ex.printStackTrace();
        }
    System.out.println("Task finished by development team Thread.currentThread().getName());
            this.countDownLatch.countDown();
    }
}

class MyQATeam extends Thread {   
    @Override
    public void run() {
        System.out.println("Task assigned to QA team");
        try {
                Thread.sleep(2000);
        } catch (InterruptedException ex) {
            ex.printStackTrace();
        }
        System.out.println("Task finished by QA team");
    }
}

উপরের কোডের আউটপুট হবে:

ডেভলপমেন্ট টিম ডিবিবিকে দায়িত্ব দেওয়া হয়েছে

ডেভলপমেন্ট টিম ডিএফএ-এর দায়িত্ব অর্পণ করা

টাস্কটি ডেভলপমেন্ট টিম ডিবি দ্বারা শেষ হয়েছে

টাস্কটি ডেভলপমেন্ট টিম ডিভা দ্বারা সমাপ্ত

কিউএ দলে দায়িত্ব অর্পণ

টাস্কটি কিউএ দল শেষ করেছে

এখানে অপেক্ষা () পদ্ধতিটি কাউন্টডাউনল্যাচ পতাকাটি 0 হয়ে যাওয়ার জন্য অপেক্ষা করে এবং কাউন্টডাউন () পদ্ধতিটি কাউন্টডাউনচ পতাকা 1 দ্বারা হ্রাস করে।

যোগদানের সীমাবদ্ধতা: উপরোক্ত উদাহরণটিও JOIN এর সাথে অর্জন করা যেতে পারে, তবে JOIN দুটি পরিস্থিতিতে ব্যবহার করা যায় না:

  1. যখন আমরা থ্রেড তৈরি করতে থ্রেড ক্লাসের পরিবর্তে এক্সিকিউটর সার্ভিস ব্যবহার করি।
  2. উপরোক্ত উদাহরণটি সংশোধন করুন যেখানে ম্যানেজার QA দলের কাছে কোড হস্তান্তর করতে চায় সাথে সাথে বিকাশ তাদের 80% টাস্কটি সম্পন্ন করে। এর অর্থ হ'ল কাউন্টডাউনল্যাচ আমাদের বাস্তবায়ন সংশোধন করার অনুমতি দেয় যা তাদের আংশিক সম্পাদনের জন্য অন্য থ্রেডের জন্য অপেক্ষা করতে ব্যবহার করা যেতে পারে।

3

অন্য সমস্ত থ্রেডের সম্পাদনটি সম্পন্ন না হওয়া পর্যন্ত কাউন্ডডাউনল্যাচ আপনাকে একটি থ্রেড অপেক্ষা করতে সক্ষম করে।

সিউডো কোড হতে পারে:

// Main thread starts
// Create CountDownLatch for N threads
// Create and start N threads
// Main thread waits on latch
// N threads completes there tasks are returns
// Main thread resume execution

আপনি কোড বিবরণ থেকে আপনার সমস্ত বিবরণ সরিয়ে নিতে চাইতে পারেন
পল লো

যদিও সেরা মন্তব্য। আমি এই তাত্ত্বিক ব্যাখ্যার পরিবর্তে মন্তব্যগুলিতে পছন্দ করি।
রেনাতোইরাউজোক

2

এরকম কিছু কখন ব্যবহার করা যায় তার একটি উত্তম উদাহরণ হ'ল জাভা সাধারণ সিরিয়াল সংযোগকারী, সিরিয়াল বন্দরগুলি অ্যাক্সেস করা। সাধারণত আপনি বন্দরে কিছু লিখবেন, এবং অ্যাসক্রোনিকভাবে, অন্য থ্রেডে, ডিভাইসটি সিরিয়ালপোর্টএভেন্টলিস্টনারটিতে প্রতিক্রিয়া জানাবে। সাধারণত, প্রতিক্রিয়াটির জন্য অপেক্ষা করতে আপনি বন্দরে লেখার পরে বিরতি দিতে চাইবেন। এই দৃশ্যের জন্য থ্রেড লকগুলি ম্যানুয়ালি হ্যান্ডেল করা অত্যন্ত জটিল, তবে কাউন্টডাউনলেট ব্যবহার করা সহজ। আপনি ভেবে যাওয়ার আগে আপনি এটি অন্য কোনও উপায়ে করতে পারেন, এমন জাতির পরিস্থিতি সম্পর্কে সতর্ক থাকুন যা আপনি কখনও ভাবেননি !!

সুডোকোড:

CountDownLatch latch;
void writeData() { 
   latch = new CountDownLatch(1);
   serialPort.writeBytes(sb.toString().getBytes())
   try {
      latch.await(4, TimeUnit.SECONDS);
    } catch (InterruptedException e) {
   }
}
class SerialPortReader implements SerialPortEventListener {
    public void serialEvent(SerialPortEvent event) {
        if(event.isRXCHAR()){//If data is available
            byte buffer[] = serialPort.readBytes(event.getEventValue());
            latch.countDown();
         }
     }
}


2

যদি আপনি ল্যাচকাউন্টডাউন () তে আপনার কল করার পরে কিছু ডিবাগ যোগ করেন তবে এটির আচরণটি আরও ভালভাবে বুঝতে আপনাকে সহায়তা করতে পারে।

latch.countDown();
System.out.println("DONE "+this.latch); // Add this debug

আউটপুট দেখায় কাউন্ট হ্রাস পাচ্ছে। এই 'গণনা' কার্যকরভাবে রান্নেবল টাস্কের সংখ্যা (প্রসেসর অবজেক্টস) যার বিরুদ্ধে আপনি কাউন্টডাউন () চালু করেননি এবং তাই ল্যাচ.ওয়ায়েট () এ কল করার মূল থ্রেডটিকে অবরুদ্ধ করা হয়েছে।

DONE java.util.concurrent.CountDownLatch@70e69696[Count = 2]
DONE java.util.concurrent.CountDownLatch@70e69696[Count = 1]
DONE java.util.concurrent.CountDownLatch@70e69696[Count = 0]

2

কাউন্টডাউনল্যাচ সম্পর্কে ওরাকল ডকুমেন্টেশন থেকে :

একটি সিঙ্ক্রোনাইজেশন সহায়তা যা অন্য থ্রেডে পরিচালিত ক্রিয়াকলাপের সেট সম্পূর্ণ না হওয়া পর্যন্ত এক বা একাধিক থ্রেড অপেক্ষা করতে দেয়।

CountDownLatchএকটি প্রদত্ত গণনা দিয়ে আরম্ভ করা হয়। awaitপদ্ধতি ব্লক পর্যন্ত বর্তমান গণনা পৌছয় আমন্ত্রণ কারণে শূন্য countDown()এবং পদ্ধতি, যার পরে সব অপেক্ষা থ্রেড মুক্তি পাচ্ছে অবিলম্বে অপেক্ষায় রয়েছেন ফিরে যাওয়ার কোন পরবর্তী আমন্ত্রণ। এটি একটি শট ঘটনা - গণনাটি পুনরায় সেট করা যায় না।

একটি কাউন্টডাউনল্যাচ একটি বহুমুখী সমন্বয় সরঞ্জাম এবং এটি বিভিন্ন উদ্দেশ্যে ব্যবহার করা যেতে পারে।

একজন CountDownLatchএর সকল লিপি গেটে অপেক্ষায় রয়েছেন অপেক্ষার invoking পর্যন্ত এটি একটি থ্রেড invoking কাউন্টডাউন দ্বারা খোলা হয় (): হুড়কা বন্ধ / উপর একটি সহজ, বা গেট হিসেবে তোলে যা একটি গণনা সঙ্গে সক্রিয়া।

একটি CountDownLatchএন সক্রিয়া পর্যন্ত এন থ্রেড কিছু পদক্ষেপ সম্পন্ন, অথবা কিছু কর্ম এন বার সম্পন্ন হয়েছে করতে এক থ্রেড অপেক্ষার ব্যবহার করা যাবে।

public void await()
           throws InterruptedException

থ্রেডটি বিঘ্নিত না হওয়া অবধি ল্যাচটি শূন্যতে গণনা না করা অবধি বর্তমান থ্রেডটির জন্য অপেক্ষা করতে বাধ্য করে।

যদি বর্তমান গণনা শূন্য হয় তবে এই পদ্ধতিটি তত্ক্ষণাত্ ফিরে আসে।

public void countDown()

ল্যাচের গণনা হ্রাস করে, গণনা শূন্যে পৌঁছে গেলে সমস্ত অপেক্ষার থ্রেড প্রকাশ করে।

যদি বর্তমান গণনা শূন্যের চেয়ে বেশি হয় তবে এটি হ্রাস করা হয়। নতুন গণনাটি যদি শূন্য হয় তবে সমস্ত অপেক্ষার থ্রেডগুলি থ্রেড শিডিয়ুলিংয়ের উদ্দেশ্যে পুনরায় সক্ষম করা হবে।

আপনার উদাহরণের ব্যাখ্যা।

  1. আপনি latchভেরিয়েবলের জন্য গণনা 3 হিসাবে সেট করেছেন

    CountDownLatch latch = new CountDownLatch(3);
  2. আপনি এটি ভাগ latchকরে নিয়েছেন কর্মী থ্রেডে:Processor

  3. তিনটি Runnableউদাহরণ Processorজমা দেওয়া হয়েছেExecutorService executor
  4. মূল থ্রেড ( App) নীচের বিবৃতি সহ শূন্য হওয়ার জন্য অপেক্ষা করছে

     latch.await();  
  5. Processor থ্রেড 3 সেকেন্ডের জন্য ঘুমায় এবং তারপরে এটি গণনা মানকে হ্রাস করে latch.countDown()
  6. প্রথম Processউদাহরণটি ল্যাচ গণনাটি সম্পূর্ণ হওয়ার পরে 2 হিসাবে পরিবর্তিত হবে latch.countDown()

  7. দ্বিতীয় Processউদাহরণটি ল্যাচ গণনাটি সম্পূর্ণ হওয়ার পরে 1 হিসাবে পরিবর্তিত হবে latch.countDown()

  8. তৃতীয় Processউদাহরণটি ল্যাচ সংখ্যা গণনা শেষ হওয়ার পরে 0 হিসাবে পরিবর্তন করবে latch.countDown()

  9. ল্যাচে জিরো গণনা মূল থ্রেড Appথেকে বেরিয়ে আসেawait

  10. অ্যাপ্লিকেশন প্রোগ্রাম এখন এই আউটপুট মুদ্রণ: Completed


2

জাভা ডকের এই উদাহরণটি আমাকে ধারণাগুলি পরিষ্কারভাবে বুঝতে সাহায্য করেছে:

class Driver { // ...
  void main() throws InterruptedException {
    CountDownLatch startSignal = new CountDownLatch(1);
    CountDownLatch doneSignal = new CountDownLatch(N);

    for (int i = 0; i < N; ++i) // create and start threads
      new Thread(new Worker(startSignal, doneSignal)).start();

    doSomethingElse();            // don't let run yet
    startSignal.countDown();      // let all threads proceed
    doSomethingElse();
    doneSignal.await();           // wait for all to finish
  }
}

class Worker implements Runnable {
  private final CountDownLatch startSignal;
  private final CountDownLatch doneSignal;
  Worker(CountDownLatch startSignal, CountDownLatch doneSignal) {
     this.startSignal = startSignal;
     this.doneSignal = doneSignal;
  }
  public void run() {
     try {
       startSignal.await();
       doWork();
       doneSignal.countDown();
     } catch (InterruptedException ex) {} // return;
  }

  void doWork() { ... }
}

ভিজ্যুয়াল ব্যাখ্যার:

এখানে চিত্র বর্ণনা লিখুন

স্পষ্টতই, CountDownLatchএকটি থ্রেড (এখানে Driver) অপেক্ষার অনুমতি দেয় যতক্ষণ না চালানো থ্রেডগুলির একগুচ্ছ (এখানে Worker) তাদের সম্পাদন সম্পন্ন হয়।


1

জাভাডক ( https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/CountDownLatch.html ) তে উল্লিখিত হিসাবে , কাউন্টডাউনল্যাচ জাভা 5-তে প্রবর্তিত একটি সিঙ্ক্রোনাইজেশন সহায়তা Here এখানে সিঙ্ক্রোনাইজেশন হয় না একটি সমালোচনা বিভাগে অ্যাক্সেস সীমাবদ্ধ মানে। বরং বিভিন্ন থ্রেড ক্রিয়া ক্রম। কাউন্টডাউনল্যাচের মাধ্যমে যে ধরণের সিঙ্ক্রোনাইজেশন অর্জন করা হয়েছে তা যোগদানের মতো। ধরে নিন যে একটি থ্রেড "এম" রয়েছে যা অন্যান্য কর্মের থ্রেডগুলির জন্য অপেক্ষা করতে হবে "টি 1", "টি 2", "টি 3" জাভা 1.5 এর আগে, যেভাবে এটি করা যেতে পারে, এম নিম্নলিখিত কোডটি চালাচ্ছেন

    T1.join();
    T2.join();
    T3.join();

উপরের কোডটি নিশ্চিত করে যে থ্রেড এম টি 1, টি 2, টি 3 এর কাজ শেষ করার পরে পুনরায় কাজ শুরু করবে। টি 1, টি 2, টি 3 কোনও ক্রমে তাদের কাজ শেষ করতে পারে। কাউন্টডাউনল্যাচের মাধ্যমে একই অর্জন করা যায়, যেখানে টি 1, টি 2, টি 3 এবং থ্রেড এম একই কাউন্টডাউনল্যাচ অবজেক্টটি ভাগ করে।
"এম" অনুরোধ: countDownLatch.await();
যেখানে "টি 1", "টি 2", "টি 3" হিসাবে রয়েছে countDownLatch.countdown();

যোগদানের পদ্ধতির সাথে একটি অসুবিধা হ'ল এম টি টি 1, টি 2, টি 3 সম্পর্কে জানতে হবে। যদি পরে কোনও নতুন কর্মী থ্রেড টি 4 যুক্ত হয়, তবে এম এটি সম্পর্কেও সচেতন হতে হবে। এটি কাউন্টডাউনল্যাচের সাথে এড়ানো যায়। প্রয়োগের পরে ক্রমের ক্রম হবে [টি 1, টি 2, টি 3] (টি 1, টি 2, টি 3 এর ক্রম যেভাবেই হতে পারে) -> [এম]



0
package practice;

import java.util.concurrent.CountDownLatch;

public class CountDownLatchExample {

    public static void main(String[] args) throws InterruptedException {
        CountDownLatch c= new CountDownLatch(3);  // need to decrements the count (3) to zero by calling countDown() method so that main thread will wake up after calling await() method 
        Task t = new Task(c);
        Task t1 = new Task(c);
        Task t2 = new Task(c);
        t.start();
        t1.start();
        t2.start();
        c.await(); // when count becomes zero main thread will wake up 
        System.out.println("This will print after count down latch count become zero");
    }
}

class Task extends Thread{
    CountDownLatch c;

    public Task(CountDownLatch c) {
        this.c = c;
    }

    @Override
    public void run() {
        try {
            System.out.println(Thread.currentThread().getName());
            Thread.sleep(1000);
            c.countDown();   // each thread decrement the count by one 
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.