কনকারেন্সি, ব্লকিং কিউ (জাভা 7) - 1

"হাই, অ্যামিগো!"

"হাই কিম!"

"আজ, আমি আপনাকে একত্রীকরণ সম্পর্কে বলতে যাচ্ছি।"

" Concurrency হল একটি জাভা ক্লাস লাইব্রেরি যা বিশেষ ক্লাসগুলিকে অন্তর্ভুক্ত করে যেগুলি একাধিক থ্রেড থেকে কাজের জন্য অপ্টিমাইজ করা হয়েছে৷ এটি একটি খুব আকর্ষণীয় এবং বিস্তৃত বিষয়৷ কিন্তু আজ আমরা শুধু একটি ভূমিকা পেতে যাচ্ছি৷ প্যাকেজটিকে বলা হয় java.util৷ সমবর্তী প্যাকেজ। আমি আপনাকে কয়েকটি আকর্ষণীয় ক্লাসের কথা বলব।"

" পারমাণবিক প্রকার। "

"আপনি ইতিমধ্যেই জানেন যে এমনকি গণনা++ একটি থ্রেড-নিরাপদ অপারেশন নয়। যখন একটি ভেরিয়েবল 1 দ্বারা বৃদ্ধি পায়, তখন তিনটি ক্রিয়াকলাপ ঘটে। ফলস্বরূপ, ভেরিয়েবল পরিবর্তন করা হলে একটি বিরোধ হতে পারে।"

"হ্যাঁ, এলি আমাকে অনেক আগেই বলেছিল:"

থ্রেড 1 থ্রেড 2 ফলাফল
register1 = count;
register1++;
count = register1;
register2 = count;
register2++;
count = register2;
register1 = count;
register2 = count;
register2++;
count = register2;
register1++;
count = register1;

"ঠিক। তারপর জাভা এই ক্রিয়াকলাপগুলিকে এক হিসাবে সম্পাদন করার জন্য ডেটা প্রকারগুলি যুক্ত করেছে, অর্থাৎ পারমাণবিকভাবে (একটি পরমাণু অবিভাজ্য)।"

"উদাহরণস্বরূপ, জাভাতে রয়েছে AtomicInteger, AtomicBoolian, AtomicDouble ইত্যাদি।"

"ধরুন আমাদের একটি «কাউন্টার» ক্লাস করতে হবে:"

উদাহরণ
class Counter
{
 private int c = 0;

 public void increment()
 {
  c++;
 }

 public void decrement()
 {
  c--;
 }

 public int value()
 {
  return c;
 }
}

"আপনি কিভাবে এই শ্রেণীর থ্রেড-নিরাপদ বস্তু তৈরি করবেন?"

"ঠিক আছে, আমি সমস্ত পদ্ধতি সিঙ্ক্রোনাইজ করব এবং এটি দিয়ে সম্পন্ন করব:"

উদাহরণ
class synchronized Counter
{
 private int c = 0;

 public synchronized void increment()
 {
  c++;
 }

 public synchronized void decrement()
 {
  c--;
 }

 public synchronized int value()
 {
  return c;
 }
}

"ভাল কাজ। কিন্তু, আমরা যদি পারমাণবিক প্রকারগুলি ব্যবহার করি তবে এটি দেখতে কেমন হবে:"

উদাহরণ
class AtomicCounter
{
 private AtomicInteger c = new AtomicInteger(0);

 public void increment()
 {
  c.incrementAndGet();
 }

 public void decrement()
 {
  c.decrementAndGet();
 }

 public int value()
 {
  return c.get();
 }
}

"আপনার ক্লাস এবং আমার ক্লাস উভয়ই একইভাবে কাজ করে, কিন্তু AtomicInteger সহ ক্লাস দ্রুত কাজ করে।"

"আচ্ছা, এটা কি সামান্য পার্থক্য?"

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

"আমি রাজি। এটা বোঝা যায়।"

"যাইহোক, আপনি কি লক্ষ্য করেছেন যে পারমাণবিক প্রকারগুলি অপরিবর্তনীয় নয় ? আদর্শ পূর্ণসংখ্যা শ্রেণীর বিপরীতে , AtomicInteger এর অভ্যন্তরীণ অবস্থা পরিবর্তন করার পদ্ধতি রয়েছে।"

"বুঝলাম। ঠিক যেমন স্ট্রিং এবং স্ট্রিংবাফার ।"

"হ্যা অনেকটা এরকমই."

" থ্রেড-নিরাপদ সংগ্রহ। "

"এই ধরনের একটি সংগ্রহের উদাহরণ হিসাবে, আমি কি কনকারেন্টহ্যাশম্যাপ উপস্থাপন করতে পারি। আপনি কীভাবে হ্যাশম্যাপকে থ্রেড-নিরাপদ করবেন?"

"এর সমস্ত পদ্ধতি সিঙ্ক্রোনাইজ করবেন?"

"অবশ্যই, কিন্তু এখন কল্পনা করুন যে আপনার কাছে এমন একটি সিঙ্ক্রোনাইজড হ্যাশম্যাপ আছে, এবং কয়েক ডজন থ্রেড এটি অ্যাক্সেস করছে। এবং সেকেন্ডে একশ বার একটি নতুন এন্ট্রি মানচিত্রে যোগ করা হয়েছে, এবং প্রক্রিয়াটিতে পুরো বস্তুটি পড়া এবং লেখার জন্য লক করা হয়েছে।"

"ওয়েল, এটা আদর্শ পদ্ধতি। আপনি কি করতে পারেন?"

"জাভার নির্মাতারা কয়েকটি দুর্দান্ত জিনিস নিয়ে এসেছেন।"

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

"দ্বিতীয়, আপনি কি মনে রাখবেন যে আপনি তালিকা/মানচিত্রের উপাদানগুলির উপর পুনরাবৃত্তি করতে পারবেন না এবং একই সময়ে তালিকা পরিবর্তন করতে পারবেন না? এই ধরনের কোড একটি ব্যতিক্রম ছুঁড়ে দেবে:"

একটি লুপে একটি সংগ্রহের উপাদানগুলির উপর পুনরাবৃত্তি করবেন না এবং একই সাথে এটি পরিবর্তন করবেন না
HashMap<String, Integer> map = new HashMap<String, Integer>();

for (String key: map.keySet())
{
 if (map.get(key) == 0)
  map.remove(key);
}

"কিন্তু সমবর্তী হ্যাশম্যাপে, আপনি করতে পারেন:"

একটি লুপে একটি সংগ্রহের উপাদানগুলির উপর পুনরাবৃত্তি করবেন না এবং একই সাথে এটি পরিবর্তন করবেন না"
ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<String, Integer>();

for (String key: map.keySet())
{
 if (map.get(key) == 0)
  map.remove(key);
}

"সমসাময়িক প্যাকেজের অনেক সুবিধা রয়েছে। এগুলো ব্যবহার করার জন্য আমাদের এই ক্লাসগুলোকে খুব ভালোভাবে বুঝতে হবে।"

"আমি দেখছি। ধন্যবাদ, কিম। এগুলি সত্যিই আকর্ষণীয় ক্লাস। আমি আশা করি যে একদিন আমি একজন গুণী ব্যক্তির মতো তাদের আয়ত্ত করতে পারব।"