কীভাবে কনকেন্যরলিঙ্কড কিউ ব্যবহার করবেন?


96

আমি ConcurrentLinkedQueueজাভাতে কীভাবে ব্যবহার করব ?
এটি ব্যবহার করে LinkedQueue, কি আমার কি সারিতে সামঞ্জস্যতা নিয়ে উদ্বিগ্ন হওয়া দরকার? অথবা আমাকে কী কেবল দুটি পদ্ধতি সংজ্ঞায়িত করতে হবে (একটি তালিকা থেকে উপাদান পুনরুদ্ধারে এবং অন্যটি তালিকায় উপাদান যুক্ত করতে)?
দ্রষ্টব্য: অবশ্যই এই দুটি পদ্ধতি সিঙ্ক্রোনাইজ করতে হবে। ঠিক?


সম্পাদনা: আমি যা করার চেষ্টা করছি তা হ'ল: আমার একটি ক্লাস (জাভাতে) রয়েছে একটি পদ্ধতি সহ সারি থেকে আইটেমগুলি পুনরুদ্ধার করার জন্য এবং অন্য শ্রেণীর সাথে একটি পদ্ধতিতে আইটেমগুলিকে সারিতে যুক্ত করুন। তালিকা থেকে যোগ করা এবং পুনরুদ্ধার করা আইটেমগুলি আমার নিজের শ্রেণীর অবজেক্ট।

আরও একটি প্রশ্ন: অপসারণ পদ্ধতিতে আমার কি এটি করা দরকার:

while (queue.size() == 0){ 
  wait(); 
  queue.poll();
}

আমার কাছে কেবল একজন ভোক্তা এবং একজন প্রযোজক।


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

4
আপনার নিজের প্রশ্নটি সম্পাদনা করা উচিত এবং এই ব্যাখ্যাটি প্রশ্নটিতেই রাখা উচিত।
অ্যাডাম জ্যাসকিউইচ

উত্তর:


157

না, পদ্ধতিগুলি সিঙ্ক্রোনাইজ করার দরকার নেই এবং আপনার কোনও পদ্ধতি সংজ্ঞায়িত করার দরকার নেই; তারা ইতিমধ্যে কনক্র্যান্টলিঙ্কড কিউতে রয়েছে, কেবল তাদের ব্যবহার করুন। সাম্প্রতিক লিঙ্কযুক্ত কিউ আপনার অভ্যন্তরীণভাবে প্রয়োজনীয় সমস্ত লকিং এবং অন্যান্য ক্রিয়াকলাপগুলি করে; আপনার উত্পাদক (গুলি) কাতারে ডেটা যুক্ত করে এবং আপনার ভোক্তারা এটির জন্য জরিপ করে।

প্রথমে আপনার সারিটি তৈরি করুন:

Queue<YourObject> queue = new ConcurrentLinkedQueue<YourObject>();

এখন আপনি যেখানেই আপনার উত্পাদক / ভোক্তা অবজেক্ট তৈরি করছেন, সারিতে পাস করুন যাতে তাদের বস্তুগুলি রাখার জন্য কোথাও রয়েছে (পরিবর্তে আপনি এটির জন্য একটি সেটর ব্যবহার করতে পারেন, তবে আমি এই ধরণের জিনিসটি কোনও কনস্ট্রাক্টারে করতে পছন্দ করি):

YourProducer producer = new YourProducer(queue);

এবং:

YourConsumer consumer = new YourConsumer(queue);

এবং এতে আপনার প্রযোজকটিতে স্টাফ যুক্ত করুন:

queue.offer(myObject);

এবং আপনার ভোক্তাতে স্টাফ বের করুন (যদি সারিটি খালি থাকে তবে পোল () বাতিল হবে, সুতরাং এটি পরীক্ষা করুন):

YourObject myObject = queue.poll();

আরও তথ্যের জন্য জাভাদোক দেখুন

সম্পাদনা:

আপনার যদি সারিটি খালি না হওয়ার অপেক্ষায় অবরুদ্ধ করতে হয় তবে আপনি সম্ভবত একটি লিঙ্কডব্লকিংকিউ ব্যবহার করতে এবং টেক () পদ্ধতিটি ব্যবহার করতে চান। তবে, লিংকডব্লকিংকিউয়ের সর্বাধিক ক্ষমতা রয়েছে (পূর্ণসংখ্যার ডিফল্ট MA MAX_VALUE, যা দুই বিলিয়ন এরও বেশি) এবং এটি আপনার পরিস্থিতির উপর নির্ভর করে উপযুক্ত হতে পারে বা নাও পারে।

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

Queue<YourObject> queue = Collections.synchronizedList(new LinkedList<YourObject>());

এর একটি প্লাস হ'ল এটি উদাহরণ (লাইন) এ লক করে, তাই আপনি যৌগিক ক্রিয়াকলাপের পারমাণবিকতা নিশ্চিত করার জন্য কাতারে সিংক্রোনাইজ করতে পারেন (জারেড ব্যাখ্যা করেছেন)। উদাহরণস্বরূপ লকিংয়ের বাইরে (java.util.concurrent.atomic ভেরিয়েবলগুলি ব্যবহার করে) সমস্ত ক্রিয়াকলাপ যেমন করা হয় তেমনি আপনি কনকোয়ারেন্টলিঙ্কড কিউ দিয়ে এটি করতে পারবেন না। সারি খালি থাকার সময় আপনি যদি ব্লক করতে চান তবে আপনার এটি করার প্রয়োজন হবে না, কারণ পোল () সারি খালি থাকার সময় শূন্য হয়ে যাবে, এবং পোল () পারমাণবিক। জরিপ () বাতিল করে দেয় কিনা তা পরীক্ষা করে দেখুন। যদি এটি হয়, অপেক্ষা করুন (), তবে আবার চেষ্টা করুন। লক করার দরকার নেই।

শেষ অবধি:

সত্যি বলতে, আমি কেবল একটি লিঙ্কডব্লকিংকুই ব্যবহার করব। এটি এখনও আপনার আবেদনের জন্য ওভারকিল, তবে এটি কার্যকরভাবে কার্যকর হবে ds যদি এটি যথেষ্ট পারফরম্যান্ট না হয় (প্রোফাইলে!), আপনি সর্বদা অন্য কিছু চেষ্টা করতে পারেন এবং এর অর্থ এটি আপনাকে কোনও সিঙ্ক্রোনাইজড স্টাফের সাথে ডিল করতে হবে না:

BlockingQueue<YourObject> queue = new LinkedBlockingQueue<YourObject>();

queue.put(myObject); // Blocks until queue isn't full.

YourObject myObject = queue.take(); // Blocks until queue isn't empty.

অন্য সব কিছুই এক রকম। পুট সম্ভবত অবরুদ্ধ হবে না, কারণ আপনি সম্ভবত দুই বিলিয়ন বস্তুকে কাতারে রাখবেন না।


আপনার প্রতিক্রিয়ার জন্য ধন্যবাদ. আরও একটি প্রশ্ন: অপসারণ পদ্ধতিতে আমার কি এটি করা দরকার: যখন (queue.size () == 0) অপেক্ষা (); queue.poll ();
রিকার্ডো ফেলগিগ্রাস 21

আমি আমার উত্তরের সম্পাদনা হিসাবে উত্তর দেব কারণ এটি অত্যন্ত গুরুত্বপূর্ণ pretty
অ্যাডাম জ্যাসকিউইচ

অন্য প্রশ্নে বিভ্রান্তির কারণ হিসাবে, Collection.synchronizedListএমনটি প্রত্যাবর্তন করে Listযা বাস্তবায়ন করে না Queue
টম হাটিন -

@AdamJaskiewicz ব্যবহার করছে ConcurrentLinkedQueueপ্রযোজক কনজিউমার একটি ভাল ধারণা জন্য, আমি এই পোস্টে উল্লেখ করছি stackoverflow.com/questions/1426754/...
rd22

37

এটি মূলত অন্য প্রশ্নের সদৃশ

এই প্রশ্নের সাথে সম্পর্কিত যে উত্তরটির বিভাগটি এখানে:

আমি java.util.ConcurrentLinkedQueue ব্যবহার করি তবে কি আমার নিজস্ব সিঙ্ক্রোনাইজেশন করা দরকার?

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

উদাহরণস্বরূপ, এটি আপনার পক্ষ থেকে কোনও পদক্ষেপ ছাড়াই থ্রেডসেফ:

queue.add(obj);

বা

queue.poll(obj);

যাহোক; কাতারে অ-পারমাণবিক কলগুলি স্বয়ংক্রিয়ভাবে থ্রেড-নিরাপদ নয়। উদাহরণস্বরূপ, নিম্নলিখিত অপারেশন হয় না স্বয়ংক্রিয়ভাবে threadsafe:

if(!queue.isEmpty()) {
   queue.poll(obj);
}

এটি সর্বশেষ থ্রেডসেফ নয়, কারণ এটি খুব সম্ভব যে সময়ের মধ্যেই এমপিটি বলা হয় এবং সময় পোল বলা হয়, অন্যান্য থ্রেডগুলি সারি থেকে আইটেম যুক্ত বা সরিয়ে ফেলবে। এটি করার থ্রেডসেফ উপায়টি এরকম:

synchronized(queue) {
    if(!queue.isEmpty()) {
       queue.poll(obj);
    }
}

আবার ... কাতারে পারমাণবিক কলগুলি স্বয়ংক্রিয়ভাবে থ্রেড-নিরাপদ। অ-পারমাণবিক কল হয় না।


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

6
এছাড়াও আপনাকে সে সম্পর্কে সতর্কতা অবলম্বন করা উচিত। সিঙ্ক্রোনাইজডলিস্টের বিপরীতে, কনক্র্যান্টলিঙ্কড কিউ নিজেই সিঙ্ক্রোনাইজ হয় না, সুতরাং আপনার কোডটিতে কোনও প্রযোজক আপনার সিংক্রোনাইজড ব্লকে থাকা অবস্থায় কিউয়ের কাছে অফার দেওয়া এখনও সম্ভব হবে।
অ্যাডাম জ্যাসকিউইচ

আপনি কিউ.আইএসপি () এবং কুই.প্লল () একত্রিত করবেন? আপনি কি ঠিক জরিপ করে পরীক্ষা করতে পারবেন না যে ফলাফলটি শূন্য? (আমার বোধগম্যতা হল আপনি যদি খালি
সারিটি

আমি শেষ কোড ব্লক ব্যতীত আপনার কোডের সমস্ত কিছুর সাথে একমত। সাম্প্রতিক লিঙ্কযুক্ত কিউয়ে সিঙ্ক্রোনাইজ করা আপনাকে কোনওরকম গ্যারান্টি দেয় না কারণ অন্যান্য কলগুলি সিঙ্ক্রোনাইজ করা হয়নি। সুতরাং আপনার "ইস্পটি ()" এবং "পোল (...)" এর মধ্যে অন্য থ্রেড থেকে একটি "অ্যাড (..)" ঘটতে পারে যদিও আপনি এই থ্রেডটি সিঙ্ক্রোনাইজ করেছেন
ক্লিটোস জি।


6

সারিতে থাকা সমস্ত কিছু গ্রাস করার চেষ্টা করার পরে থ্রেড সুরক্ষা এবং "চমকপ্রদতা" এর ক্ষেত্রে আপনি সম্ভবত এটিই সন্ধান করছেন:

for (YourObject obj = queue.poll(); obj != null; obj = queue.poll()) {
}

এটি গ্যারান্টি দিবে যে সারিটি খালি থাকলে আপনি প্রস্থান করবেন এবং যতক্ষণ না এটি খালি না থাকে আপনি অবজেক্টগুলি পপ করা চালিয়ে যান।


একটি সারি খালি করার জন্য খুব দরকারী। ধন্যবাদ
ডেভিলকোড

2

কনক্যুরেন্টলিঙ্কড কিউইউ হ'ল একটি দক্ষ ওয়েট / লক ফ্রি বাস্তবায়ন (রেফারেন্সের জন্য জাভডোক দেখুন), তাই আপনাকে কেবল সিঙ্ক্রোনাইজ করার প্রয়োজন হবে না, তবে সারিটি কোনও কিছুই লক করবে না, এইভাবে একটি সিনক্রোনাইজ না হওয়ার মতো কার্যত তত দ্রুত (থ্রেড নয়) নিরাপদ) এক।


1

এটি যেমন আপনি অবিচ্ছিন্ন সংগ্রহ হিসাবে ব্যবহার করুন। সমকালীন [সংগ্রহ] ক্লাসগুলি নিয়মিত সংগ্রহগুলি মোড় করে দেয় যাতে আপনাকে অ্যাক্সেসের সিঙ্ক্রোনাইজ করার বিষয়ে ভাবতে হবে না।

সম্পাদনা: সমকালীন লিঙ্কযুক্ত তালিকা আসলে কেবল একটি মোড়ক নয়, বরং আরও ভাল একযোগে বাস্তবায়ন হয়। যেভাবেই হোক, আপনাকে সিঙ্ক্রোনাইজেশন সম্পর্কে চিন্তা করতে হবে না।


সাম্প্রতিক লিঙ্কযুক্ত কিউ নেই। এটি বিশেষত একাধিক উত্পাদক এবং ভোক্তাদের একযোগে অ্যাক্সেসের জন্য স্থলভাগ থেকে তৈরি।
ক্লেকশনস.সাইনক্রোনাইজড

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