কাউন্টডাউনল্যাচ বনাম সেমাফোর


95

ব্যবহারের কোনও সুবিধা আছে কি?

java.util.concurrent.CountdownLatch

পরিবর্তে

java.util.concurrent.Semaphore ?

যতদূর আমি বলতে পারি নীচের অংশগুলি প্রায় সমতুল্য:

1. সেমফোর

final Semaphore sem = new Semaphore(0);
for (int i = 0; i < num_threads; ++ i)
{
  Thread t = new Thread() {
    public void run()
    {
      try
      {
        doStuff();
      }
      finally
      {
        sem.release();
      }
    }
  };
  t.start();
}

sem.acquire(num_threads);

2: কাউন্টডাউনল্যাচ

final CountDownLatch latch = new CountDownLatch(num_threads);
for (int i = 0; i < num_threads; ++ i)
{
  Thread t = new Thread() {
    public void run()
    {
      try
      {
        doStuff();
      }
      finally
      {
        latch.countDown();
      }
    }
  };
  t.start();
}

latch.await();

# 2 ব্যতীত ল্যাচটি পুনরায় ব্যবহার করা যাবে না এবং আরও গুরুত্বপূর্ণভাবে আপনাকে কতগুলি থ্রেড তৈরি করা হবে তা আগেই জানতে হবে (বা ল্যাচ তৈরির আগে সেগুলি শুরু না হওয়া পর্যন্ত অপেক্ষা করুন))

সুতরাং কোন পরিস্থিতিতে ল্যাচ ভাল হতে পারে?

উত্তর:


112

CountDownLatchআপনার উদাহরণের ঠিক বিপরীতে ঘন ঘন ব্যবহার করা হয়। সাধারণত, await()কাউন্টাউন শূন্যে পৌঁছে গেলে আপনার একসাথে অনেকগুলি থ্রেড ব্লক হয়ে থাকবে all

final CountDownLatch countdown = new CountDownLatch(1);

for (int i = 0; i < 10; ++ i) {
   Thread racecar = new Thread() {    
      public void run() {
         countdown.await(); //all threads waiting
         System.out.println("Vroom!");
      }
   };
   racecar.start();
}
System.out.println("Go");
countdown.countDown();   //all threads start now!

আপনি এটি এমপিআই-স্টাইলে "বাধা" হিসাবে ব্যবহার করতে পারেন যার ফলে সমস্ত থ্রেড অন্য থ্রেডগুলির জন্য এগিয়ে যাওয়ার আগে একটি নির্দিষ্ট পয়েন্ট ধরে অপেক্ষা করতে পারে।

final CountDownLatch countdown = new CountDownLatch(num_thread);

for (int i = 0; i < num_thread; ++ i) {
   Thread t= new Thread() {    
      public void run() {
         doSomething();
         countdown.countDown();
         System.out.printf("Waiting on %d other threads.",countdown.getCount());
         countdown.await();     //waits until everyone reaches this point
         finish();
      }
   };
   t.start();
}

যা সব বলেছিল, CountDownLatchআপনি নিজের উদাহরণে যেভাবে দেখিয়েছেন সেটি নিরাপদে ব্যবহার করা যেতে পারে।


4
ধন্যবাদ সুতরাং আমার দুটি উদাহরণ সমান হবে না যদি একাধিক থ্রেডগুলি ল্যাচটির জন্য অপেক্ষা করতে পারে ... যদি না sem.acquire (num_threads); এর পরে sem.re দয়া করে (num_threads) ;? আমি মনে করি এটি তাদের আবার সমতুল্য করবে।
ফিনউইউ

এক অর্থে, হ্যাঁ, যতক্ষণ না প্রতিটি প্রারম্ভিক থ্রেড প্রকাশিত হয় তারপরে মুক্তি পায়। কড়া কথা বলছি, না। একটি ল্যাচ সহ, সমস্ত থ্রেড একই সাথে শুরু করার যোগ্য। সেমফোর দিয়ে, তারা একের পর এক যোগ্য হয়ে ওঠে (যার ফলে বিভিন্ন থ্রেড শিডিংয়ের ফলাফল হতে পারে)।
জেমস শেক

জাভা ডকুমেন্টেশন এটিকে বোঝায় যে এটি একটি কাউন্টডাউনল্যাচ তার উদাহরণের সাথে যথাযথভাবে ফিট করে: ডকস.ওরকল / জাভ্যাস / ১.০.০ / ডকস / এপি / জাভা / ইউটিল / কনকোভার্ট / … বিশেষত, "এন থেকে সূচনাপ্রাপ্ত একটি কাউন্টডাউনল্যাচ এন থ্রেড কিছু ক্রিয়া সম্পন্ন না করা পর্যন্ত, বা কিছু ক্রিয়া এন বার সম্পন্ন না হওয়া পর্যন্ত একটি থ্রেড অপেক্ষা করতে ব্যবহৃত হতে পারে" "
ক্রিস মরিস

তুমি ঠিক. আমি আমার উত্তরটি কিছুটা প্রতিবিম্বিত করার জন্য এটি আপডেট করব যে এটি কাউন্টডাউনল্যাচের সবচেয়ে সাধারণ ব্যবহার যা আমি বনাম দেখেছি এটি হ'ল উদ্দেশ্য।
জেমস শেক

11
এটি এই প্রশ্নের উত্তর দেয় কাউন্টডাউনল্যাচের সবচেয়ে ঘন ঘন ব্যবহার কী? এটি একটি সেমফোরের উপরে একটি কাউন্টডাউনল্যাচ ব্যবহারের সুবিধা / পার্থক্য সম্পর্কিত মূল প্রশ্নের উত্তর দেয় না।
মার্কো ল্যাকোভিচ

67

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

সেমোফোরটি রিসোর্স ব্যবহার করছে এমন সমবর্তী থ্রেডগুলির সংখ্যা নিয়ন্ত্রণ করতে ব্যবহৃত হয়। এই সংস্থানটি কোনও ফাইলের মতো কিছু হতে পারে বা চালানো থ্রেডের সংখ্যা সীমাবদ্ধ করে সিপিইউ হতে পারে। একটি সেমফোর্ উপর গণনা পর্যন্ত যেতে এবং নিচে বিভিন্ন থ্রেড কল হিসাবে পারেন acquire()এবং release()

আপনার উদাহরণে, আপনি মূলত কাউন্ট ইউপি ল্যাচের ধরণের হিসাবে সেমাফোরটি ব্যবহার করছেন । প্রদত্ত যে আপনার অভিপ্রায়টি সমস্ত থ্রেড সমাপ্তির জন্য অপেক্ষা করা উচিত, তা ব্যবহার করে CountdownLatchআপনার উদ্দেশ্যটি আরও পরিষ্কার হয়।


23

সংক্ষিপ্ত সারাংশ:

  1. Semaphoreএবং CountDownLatchবিভিন্ন উদ্দেশ্যে কাজ করে।

  2. Semaphoreরিসোর্সে থ্রেড অ্যাক্সেস নিয়ন্ত্রণ করতে ব্যবহার করুন ।

  3. CountDownLatchসমস্ত থ্রেড সমাপ্তির জন্য অপেক্ষা করতে ব্যবহার করুন

Semaphore জাভাডোকস থেকে সংজ্ঞা:

একটি Semaphoreঅনুমতিপত্রের একটি সেট বজায় রাখে। পারমিট না পাওয়া acquire()পর্যন্ত প্রতিটি ব্লক প্রয়োজনীয় হয় এবং তারপরে এটি গ্রহণ করে। প্রত্যেকে সম্ভাব্যভাবে একটি ব্লককারী অর্জনকারীকে মুক্তি দিয়ে একটি অনুমতি যুক্ত করে।release()

তবে, কোনও আসল অনুমতি বস্তু ব্যবহার করা হয় না; Semaphoreশুধু গণনা প্রাপ্তিসাধ্য রাখে এবং সেই অনুযায়ী কাজ করে।

এটা কিভাবে কাজ করে?

সেমোফোর্সগুলি রিসোর্স ব্যবহার করে এমন সমবর্তী থ্রেডগুলির সংখ্যা নিয়ন্ত্রণ করতে ব্যবহৃত হয় hat এই সংস্থানটি কোনও শেয়ারড ডেটা বা কোডের একটি ব্লক ( সমালোচনামূলক বিভাগ ) বা কোনও ফাইলের মতো হতে পারে।

একটি উপর গণনা Semaphoreপর্যন্ত যেতে এবং নিচে বিভিন্ন থ্রেড কল হিসাবে পারেন acquire()এবং release()। তবে যে কোনও সময়, আপনার কাছে সেমফোর কাউন্টের চেয়ে বেশি সংখ্যক থ্রেড থাকতে পারে না।

Semaphore ব্যবহারের ক্ষেত্রে:

  1. ডিস্কে একযোগে অ্যাক্সেস সীমাবদ্ধ করা (প্রতিযোগী ডিস্কের সন্ধানের কারণে এটি পারফরম্যান্সকে হত্যা করতে পারে)
  2. থ্রেড তৈরির সীমাবদ্ধ
  3. জেডিবিসি সংযোগ পুলিং / সীমাবদ্ধ
  4. নেটওয়ার্ক সংযোগ থ্রোটলিং
  5. থ্রোটলিং সিপিইউ বা মেমরি নিবিড় কাজগুলি

Semaphore ব্যবহারের জন্য এই নিবন্ধটি দেখুন ।

CountDownLatch জাভাডোকস থেকে সংজ্ঞা:

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

এটা কিভাবে কাজ করে?

CountDownLatchএকটি কাউন্টার দিয়ে থ্রেড সংখ্যার সাথে ইনিশিয়েলড হয়ে কাজ করে, যা প্রতিবার একটি থ্রেডের সম্পাদন সম্পন্ন করার পরে হ্রাস হয়। যখন গণনা শূন্যে পৌঁছে যায়, এর অর্থ সমস্ত থ্রেডগুলি তাদের সম্পাদন সম্পন্ন করে, এবং ল্যাডের অপেক্ষায় থাকা থ্রেড কার্যকর করে আবার শুরু করে।

CountDownLatch ব্যবহারের ক্ষেত্রে:

  1. সর্বাধিক সমান্তরালতা অর্জন: কখনও কখনও আমরা সর্বাধিক সমান্তরালতা অর্জন করতে একই সাথে কয়েকটি থ্রেড শুরু করতে চাই
  2. সম্পাদনা শুরুর আগে এন থ্রেডগুলি সম্পূর্ণ করতে অপেক্ষা করুন
  3. ডেডলক সনাক্তকরণ।

পরিষ্কারভাবে ধারণাগুলি বুঝতে এই নিবন্ধটি দেখুন CountDownLatch

এই নিবন্ধটিতেও ফোর্ক জয়েন পুলটিতে একবার দেখুন । এর কিছু মিল রয়েছে ।CountDownLatch


7

বলুন যে আপনি চারপাশের সন্ধানের আশায় গল্ফ প্রো শপ এ গিয়েছিলেন,

আপনি যখন প্রো প্রো শপ পরিচারকদের মধ্যে একজনের কাছ থেকে টি সময় পাওয়ার জন্য লাইনে দাঁড়ান, মূলত আপনি proshopVendorSemaphore.acquire()একবার ফোন করেছিলেন , একবার আপনি একবার টি পান, আপনি ডেকেছিলেন। proshopVendorSemaphore.release()দ্রষ্টব্য: ফ্রি অ্যাটেন্ডেন্টগুলির মধ্যে যে কোনও একটি আপনাকে ভাগ করতে পারে, অর্থাত্ শেয়ারড রিসোর্স service

এখন আপনি স্টার্টার পর্যন্ত পদব্রজে ভ্রমণ, তিনি একটি শুরু হয় CountDownLatch(4)এবং কলের await()অন্যদের জন্য অপেক্ষা করতে, আপনার পক্ষ জন্য আপনাকে চেক-ইন অর্থাত বলা CountDownLatchcountDown()এবং তাই চৌবাচ্চা বাকি আছে। যখন সমস্ত উপস্থিত হয়, স্টার্টার এগিয়ে যেতে দেয় ( await()কল রিটার্ন)

এখন, নয়টি ছিদ্রের পরে যখন আপনি প্রত্যেকে বিরতি নেবেন, অনুমানের সাথে আবার স্টার্টারকে জড়িত করতে পারেন, তিনি CountDownLatch(4)হোল 10 কে ছাড়ানোর জন্য 'নতুন' ব্যবহার করেন, হোল 1 এর মতো একই প্রতীক্ষা / সিঙ্ক করুন।

তবে, যদি স্টার্টারটি CyclicBarrierশুরু করতে একটি ব্যবহার করে , তবে তিনি দ্বিতীয় দোলের পরিবর্তে হোল 10 এ একই ঘটনা পুনরায় সেট করতে পারেন, যা ব্যবহার এবং নিক্ষেপ করে।


4
আমি আপনার উত্তরটি বুঝতে পেরেছি তা নিশ্চিত নই, তবে আপনি যদি কাউন্টডাউনল্যাচ এবং সেম্যাফোর কীভাবে কাজ করে তা বর্ণনা করার চেষ্টা করছেন তবে এটি প্রশ্নের বিষয় নয়।
ফিনউইউ

10
দুর্ভাগ্যক্রমে আমি গল্ফ সম্পর্কে কিছুই জানি না।
রিং বহনকারী

তবে স্টার্টার স্টাফগুলি .Aquire (প্লেয়ার) দিয়ে করা এবং মুক্তির সাথে প্রকাশিত গণনা বাড়ানো ঠিক যেমন করা যায়। কাউন্টডাউনট্যাচটি কেবল কম কার্যকারিতা বলে মনে হচ্ছে এবং পুনরায় ব্যবহারযোগ্যতা নেই।
লাসি কিনুনুনেন

1

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


0

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

Semaphoreথ্রেডকে পারমিটগুলি পুনরুদ্ধার করতে অনুমতি দেয়, যা একসাথে অনেকগুলি থ্রেড কার্যকর করতে বাধা দেয়, যদি অনুমতি নিতে না পারে তবে এটি অবরুদ্ধ করে রাখে। Semaphoreঅন্যান্য অপেক্ষার থ্রেডগুলি এগিয়ে যাওয়ার অনুমতি দিয়ে অনুমতিগুলি ফেরত দেওয়া যেতে পারে ।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.