নন-ব্লকিং সারি

থ্রেড-নিরাপদ এবং সবচেয়ে গুরুত্বপূর্ণভাবে সংযুক্ত নোডগুলিতে নন-ব্লকিং সারি বাস্তবায়ন।

ConcurrentLinkedQueue<E> - এটি আবর্জনা সংগ্রহকারীর সাথে কাজ করার জন্য অভিযোজিত একটি অপেক্ষা-মুক্ত অ্যালগরিদম ব্যবহার করে। এই অ্যালগরিদমটি বেশ দক্ষ এবং খুব দ্রুত, কারণ এটি CAS-তে নির্মিত। সাইজ() পদ্ধতিটিদীর্ঘ সময়ের জন্য চলতে পারে, তাই এটিকে সব সময় না টানানোই ভালো।

ConcurrentLinkedDeque<E> - Deque মানে Double ended queue। এর মানে হল যে ডেটা যোগ করা যাবে এবং উভয় দিক থেকে টানা যাবে। তদনুসারে, ক্লাসটি অপারেশনের উভয় মোড সমর্থন করে: FIFO (ফার্স্ট ইন ফার্স্ট আউট) এবং LIFO (লাস্ট ইন ফার্স্ট আউট)।

অনুশীলনে, LIFO একেবারে প্রয়োজনীয় হলে ConcurrentLinkedDeque ব্যবহার করা উচিত, যেহেতু নোডগুলির দ্বিমুখীতার কারণে, এই ক্লাসটি ConcurrentLinkedQueue- এর তুলনায় অর্ধেক কার্যক্ষমতা হারায় ।

import java.util.concurrent.ConcurrentLinkedQueue;

public class  ConcurrentLinkedQueueExample {
   public static void main(String[] args) {
       ConcurrentLinkedQueue<String> queue = new ConcurrentLinkedQueue<>();

       Thread producer = new Thread(new Producer(queue));
       Thread consumer = new Thread(new Consumer(queue));

       producer.start();
       consumer.start();
   }
}

class Producer implements Runnable {

   ConcurrentLinkedQueue<String> queue;
   Producer(ConcurrentLinkedQueue<String> queue){
       this.queue = queue;
   }
   public void run() {
       System.out.println("Class for adding items to the queue");
       try {
           for (int i = 1; i < 5; i++) {
               queue.add("Item #" + i);
               System.out.println("Added: Item #" + i);
               Thread.sleep(300);
           }
       } catch (InterruptedException ex) {
           ex.printStackTrace();
           Thread.currentThread().interrupt();
       }
   }
}

class Consumer implements Runnable {

   ConcurrentLinkedQueue<String> queue;
   Consumer(ConcurrentLinkedQueue<String> queue){
       this.queue = queue;
   }

   public void run() {
       String str;
       System.out.println("Class for getting items from the queue");
       for (int x = 0; x < 5; x++) {
           while ((str = queue.poll()) != null) {
               System.out.println("Pulled out: " + str);
           }
           try {
               Thread.sleep(600);
           } catch (InterruptedException ex) {
               ex.printStackTrace();
               Thread.currentThread().interrupt();
           }
       }
   }
}

সারি ব্লক করা

BlockingQueue<E> ইন্টারফেস - যদি প্রচুর ডেটা থাকে, তাহলে ConcurrentLinkedQueue যথেষ্ট নয়।

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

BlockingQueue নাল উপাদান চিনতে পারে না এবং একটি NullPointerException নিক্ষেপ করে যখন এই ধরনের একটি উপাদান যোগ করার বা পাওয়ার চেষ্টা করে। টাইমআউটের মধ্যে সারিতে কোনো উপাদান না থাকলে পোল পদ্ধতিটি একটি শূন্য উপাদান প্রদান করে।

ব্লকিং কিউ<E> বাস্তবায়ন

আসুন আমাদের ব্লকিং কিউ বাস্তবায়নের প্রতিটি ঘনিষ্ঠভাবে দেখে নেওয়া যাক :

ArrayBlockingQueue<E> হল ক্লাসিক রিং বাফারে নির্মিত একটি ব্লকিং কিউ ক্লাস। এখানে আমাদের লকগুলির "সততা" পরিচালনা করার সুযোগ রয়েছে। যদি fair=false (ডিফল্ট), তাহলে থ্রেড অর্ডার নিশ্চিত করা হয় না।

DelayQueue<E expends Delayed> হল এমন একটি ক্লাস যা আপনাকে একটি নির্দিষ্ট বিলম্বের পরেই সারির থেকে উপাদানগুলিকে টেনে আনতে দেয়, প্রতিটি উপাদানে Delayed ইন্টারফেসের getDelay পদ্ধতির মাধ্যমে সংজ্ঞায়িত করা হয় ।

LinkedBlockingQueue<E> হল লিঙ্ক করা নোডের একটি ব্লকিং সারি, যা "টু লক কিউ" অ্যালগরিদমে প্রয়োগ করা হয়: প্রথম লকটি যোগ করার জন্য, দ্বিতীয়টি হল সারি থেকে একটি উপাদান টেনে আনার জন্য। লকগুলির কারণে, ArrayBlockingQueue- এর তুলনায় , এই শ্রেণীর উচ্চ কার্যক্ষমতা রয়েছে, কিন্তু এটির জন্য আরও মেমরির প্রয়োজন। সারির আকার কনস্ট্রাক্টরের মাধ্যমে সেট করা হয়েছে এবং ডিফল্টরূপে Integer.MAX_VALUE এর সমান।

PriorityBlockingQueue<E> হল PriorityQueue-এর উপর একটি মাল্টি-থ্রেডেড র‍্যাপার। যে যুক্তি দ্বারা উপাদান যোগ করা হবে তার জন্য তুলনাকারী দায়ী। ক্ষুদ্রতম উপাদানটি প্রথমে বেরিয়ে আসে।

সিঙ্ক্রোনাস সারি <E> - সারি FIFO (ফার্স্ট-ইন-ফার্স্ট-আউট) নীতি অনুসারে কাজ করে। প্রতিটি সন্নিবেশ অপারেশন "উৎপাদক" থ্রেডটিকে ব্লক করে যতক্ষণ না "ভোক্তা" থ্রেড উপাদানটিকে সারি থেকে টেনে না নেয় এবং বিপরীতভাবে, "উৎপাদক" উপাদানটি সন্নিবেশ না করা পর্যন্ত "ভোক্তা" অপেক্ষা করবে।

BlockingDeque<E> হল একটি ইন্টারফেস যা একটি দ্বিমুখী ব্লকিং সারির জন্য অতিরিক্ত পদ্ধতি বর্ণনা করে। ডেটা সন্নিবেশ করা যেতে পারে এবং সারির উভয় দিক থেকে বের করে আনা যায়।

LinkedBlockingDeque<E> হল লিঙ্ক করা নোডগুলিতে একটি দ্বিমুখী ব্লকিং সারি, যা একটি লক সহ একটি সাধারণ দ্বিমুখী তালিকা হিসাবে প্রয়োগ করা হয়। সারির আকার কনস্ট্রাক্টরের মাধ্যমে সেট করা হয়েছে এবং ডিফল্টরূপে Integer.MAX_VALUE এর সমান।

TransferQueue<E> - ইন্টারফেসটি আকর্ষণীয় যে যখন একটি উপাদান সারিতে যোগ করা হয়, তখনঅন্য উপভোক্তা থ্রেড সারিতে থেকে উপাদানটিকে না টেনে না আসা পর্যন্ত প্রযোজক থ্রেড সন্নিবেশ করাকে ব্লক করা সম্ভব। এছাড়াও আপনি একটি নির্দিষ্ট সময়সীমার জন্য একটি চেক যোগ করতে পারেন বা মুলতুবি থাকা গ্রাহকদের জন্য একটি চেক সেট করতে পারেন ৷ ফলস্বরূপ, আমরা অ্যাসিঙ্ক্রোনাস এবং সিঙ্ক্রোনাস বার্তাগুলির সমর্থন সহ একটি ডেটা স্থানান্তর প্রক্রিয়া পাই৷

LinkedTransferQueue<E> হল স্ল্যাক অ্যালগরিদম সহ দ্বৈত সারিগুলির উপর ভিত্তি করে ট্রান্সফার কিউ-এর একটি বাস্তবায়ননিষ্ক্রিয় থাকা অবস্থায় CAS (উপরে দেখুন) এবং থ্রেড পার্কিংয়ের ভারী ব্যবহার করে।