থ্রেডিংয়ের মাধ্যমে আরও ভাল পারফরম্যান্স

অ্যান্ড্রয়েডে থ্রেডের পারদর্শী ব্যবহার করা আপনাকে আপনার অ্যাপের কর্মক্ষমতা বাড়াতে সাহায্য করতে পারে। এই পৃষ্ঠাটি থ্রেডের সাথে কাজ করার বিভিন্ন দিক নিয়ে আলোচনা করে: UI, বা প্রধান, থ্রেডের সাথে কাজ করা; অ্যাপের জীবনচক্র এবং থ্রেড অগ্রাধিকারের মধ্যে সম্পর্ক; এবং, থ্রেড জটিলতা পরিচালনা করতে সাহায্য করার জন্য প্ল্যাটফর্ম যে পদ্ধতিগুলি প্রদান করে। এই ক্ষেত্রগুলির প্রতিটিতে, এই পৃষ্ঠাটি তাদের এড়ানোর জন্য সম্ভাব্য ক্ষতি এবং কৌশলগুলি বর্ণনা করে৷

প্রধান থ্রেড

যখন ব্যবহারকারী আপনার অ্যাপ চালু করে, তখন অ্যান্ড্রয়েড একটি এক্সিকিউশন থ্রেড সহ একটি নতুন লিনাক্স প্রক্রিয়া তৈরি করে। এই প্রধান থ্রেড, যা UI থ্রেড নামেও পরিচিত, অনস্ক্রিন যা ঘটে তার জন্য দায়ী। এটি কিভাবে কাজ করে তা বোঝার মাধ্যমে আপনি আপনার অ্যাপটিকে সবচেয়ে ভালো পারফরম্যান্সের জন্য মূল থ্রেড ব্যবহার করতে ডিজাইন করতে সাহায্য করতে পারেন।

অভ্যন্তরীণ

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

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

একটি অ্যানিমেশন বা স্ক্রিন আপডেট হওয়ার সময়, সিস্টেমটি প্রতি সেকেন্ডে 60 ফ্রেমে মসৃণভাবে রেন্ডার করার জন্য প্রতি 16 মিসে বা তার পরে কাজের একটি ব্লক (যা স্ক্রিন আঁকার জন্য দায়ী) চালানোর চেষ্টা করে। সিস্টেমটি এই লক্ষ্যে পৌঁছানোর জন্য, UI/View শ্রেণিবিন্যাসকে অবশ্যই প্রধান থ্রেডে আপডেট করতে হবে। যাইহোক, যখন মূল থ্রেডের মেসেজিং সারিতে এমন টাস্ক থাকে যা হয় খুব বেশি বা অনেক লম্বা হয় যা প্রধান থ্রেডের জন্য যথেষ্ট দ্রুত আপডেট সম্পূর্ণ করার জন্য, অ্যাপটিকে এই কাজটিকে একটি ওয়ার্কার থ্রেডে নিয়ে যাওয়া উচিত। যদি মূল থ্রেডটি 16ms এর মধ্যে কাজের ব্লকগুলি সম্পাদন করা শেষ করতে না পারে তবে ব্যবহারকারী ইনপুট করার জন্য হিচিং, ল্যাগিং বা UI প্রতিক্রিয়াশীলতার অভাব লক্ষ্য করতে পারে। যদি মূল থ্রেডটি প্রায় পাঁচ সেকেন্ডের জন্য অবরুদ্ধ থাকে, সিস্টেমটি অ্যাপ্লিকেশন নট রেসপন্ডিং (ANR) ডায়ালগ প্রদর্শন করে, যা ব্যবহারকারীকে সরাসরি অ্যাপটি বন্ধ করতে দেয়।

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

থ্রেড এবং UI অবজেক্ট রেফারেন্স

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

রেফারেন্স সহ সমস্যা দুটি স্বতন্ত্র বিভাগে পড়ে: স্পষ্ট উল্লেখ এবং অন্তর্নিহিত উল্লেখ।

স্পষ্ট উল্লেখ

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

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

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

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

এই ধরনের পরিস্থিতির সাথে, আমরা পরামর্শ দিই যে আপনার অ্যাপে থ্রেডেড কাজের টাস্কে UI অবজেক্টের সুস্পষ্ট রেফারেন্স অন্তর্ভুক্ত করবেন না। এই ধরনের রেফারেন্স এড়িয়ে চলা আপনাকে এই ধরনের মেমরি লিক এড়াতে সাহায্য করে, পাশাপাশি থ্রেডিং বিতর্ক থেকেও দূরে থাকে।

সব ক্ষেত্রে, আপনার অ্যাপের শুধুমাত্র মূল থ্রেডে UI অবজেক্ট আপডেট করা উচিত। এর মানে হল যে আপনার একটি আলোচনার নীতি তৈরি করা উচিত যা একাধিক থ্রেডকে মূল থ্রেডে কাজের সাথে যোগাযোগ করার অনুমতি দেয়, যা প্রকৃত UI অবজেক্ট আপডেট করার সাথে শীর্ষস্থানীয় কার্যকলাপ বা খণ্ডকে কাজ করে।

অন্তর্নিহিত রেফারেন্স

থ্রেডেড বস্তুর সাথে একটি সাধারণ কোড-ডিজাইন ত্রুটি নীচের কোডের স্নিপেটে দেখা যেতে পারে:

কোটলিন

class MainActivity : Activity() {
    // ...
    inner class MyAsyncTask : AsyncTask<Unit, Unit, String>() {
        override fun doInBackground(vararg params: Unit): String {...}
        override fun onPostExecute(result: String) {...}
    }
}

জাভা

public class MainActivity extends Activity {
  // ...
  public class MyAsyncTask extends AsyncTask<Void, Void, String>   {
    @Override protected String doInBackground(Void... params) {...}
    @Override protected void onPostExecute(String result) {...}
  }
}

এই স্নিপেটের ত্রুটি হল যে কোডটি থ্রেডিং অবজেক্ট MyAsyncTask কিছু কার্যকলাপের একটি অ-স্থির অভ্যন্তরীণ শ্রেণী হিসাবে ঘোষণা করে (বা কোটলিনের একটি অভ্যন্তরীণ শ্রেণী)। এই ঘোষণাটি আবদ্ধ Activity উদাহরণের একটি অন্তর্নিহিত রেফারেন্স তৈরি করে। ফলস্বরূপ, থ্রেডেড কাজ সম্পূর্ণ না হওয়া পর্যন্ত অবজেক্টটিতে কার্যকলাপের একটি রেফারেন্স রয়েছে, যার ফলে উল্লেখিত কার্যকলাপের ধ্বংস হতে বিলম্ব হয়। এই বিলম্ব, ঘুরে, স্মৃতিতে আরও চাপ দেয়।

এই সমস্যার একটি সরাসরি সমাধান হল আপনার ওভারলোড করা ক্লাসের দৃষ্টান্তগুলিকে স্ট্যাটিক ক্লাস হিসাবে বা তাদের নিজস্ব ফাইলগুলিতে সংজ্ঞায়িত করা হবে, এইভাবে অন্তর্নিহিত রেফারেন্স মুছে ফেলা হবে।

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

থ্রেড এবং অ্যাপ কার্যকলাপ জীবনচক্র

অ্যাপের জীবনচক্র আপনার অ্যাপ্লিকেশনে থ্রেডিং কীভাবে কাজ করে তা প্রভাবিত করতে পারে। একটি ক্রিয়াকলাপ ধ্বংস হওয়ার পরে একটি থ্রেড থাকা উচিত বা করা উচিত নয় তা আপনাকে সিদ্ধান্ত নিতে হতে পারে। থ্রেড অগ্রাধিকারের মধ্যে সম্পর্ক এবং অগ্রভাগে বা পটভূমিতে একটি কার্যকলাপ চলছে কিনা তাও আপনার সচেতন হওয়া উচিত।

স্থায়ী থ্রেড

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

একটি কেস বিবেচনা করুন যেখানে একটি কার্যকলাপ থ্রেডেড কাজের ব্লকগুলির একটি সেট তৈরি করে এবং তারপরে একজন কর্মী থ্রেড ব্লকগুলি কার্যকর করার আগে ধ্বংস হয়ে যায়। ফ্লাইটে থাকা ব্লকগুলির সাথে অ্যাপটির কী করা উচিত?

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

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

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

থ্রেড অগ্রাধিকার

প্রসেস এবং অ্যাপ্লিকেশান লাইফসাইকেলে বর্ণিত হিসাবে, আপনার অ্যাপের থ্রেডগুলি যে অগ্রাধিকার পায় তা আংশিকভাবে অ্যাপের লাইফসাইকেলে অ্যাপটি কোথায় রয়েছে তার উপর নির্ভর করে। আপনি আপনার অ্যাপ্লিকেশনে থ্রেড তৈরি এবং পরিচালনা করার সময়, তাদের অগ্রাধিকার সেট করা গুরুত্বপূর্ণ যাতে সঠিক থ্রেডগুলি সঠিক সময়ে সঠিক অগ্রাধিকার পায়। যদি খুব বেশি সেট করা হয়, আপনার থ্রেড UI থ্রেড এবং RenderThread কে বাধাগ্রস্ত করতে পারে, যার ফলে আপনার অ্যাপ ফ্রেম ড্রপ করে। খুব কম সেট করা হলে, আপনি আপনার অ্যাসিঙ্ক কাজগুলিকে (যেমন ইমেজ লোড করা) প্রয়োজনের চেয়ে ধীর করতে পারেন৷

প্রতিবার আপনি একটি থ্রেড তৈরি করার সময়, আপনার setThreadPriority() কল করা উচিত। সিস্টেমের থ্রেড সময়সূচী উচ্চ অগ্রাধিকার সহ থ্রেডগুলিকে অগ্রাধিকার দেয়, সেই অগ্রাধিকারগুলির ভারসাম্য বজায় রেখে অবশেষে সমস্ত কাজ সম্পন্ন করার প্রয়োজন হয়। সাধারণত, ফোরগ্রাউন্ড গ্রুপের থ্রেডগুলি ডিভাইস থেকে মোট এক্সিকিউশন সময়ের প্রায় 95% পায় , যখন ব্যাকগ্রাউন্ড গ্রুপটি মোটামুটি 5% পায়।

সিস্টেমটি Process ক্লাস ব্যবহার করে প্রতিটি থ্রেডের নিজস্ব অগ্রাধিকার মান নির্ধারণ করে।

ডিফল্টরূপে, সিস্টেমটি একটি থ্রেডের অগ্রাধিকার একই অগ্রাধিকার এবং স্পোনিং থ্রেডের মতো গ্রুপ সদস্যতা নির্ধারণ করে। যাইহোক, আপনার অ্যাপ্লিকেশন স্পষ্টভাবে setThreadPriority() ব্যবহার করে থ্রেড অগ্রাধিকার সামঞ্জস্য করতে পারে।

Process ক্লাস আপনার অ্যাপ থ্রেড অগ্রাধিকার সেট করতে ব্যবহার করতে পারে এমন একটি ধ্রুবক সেট প্রদান করে অগ্রাধিকার মান নির্ধারণে জটিলতা কমাতে সাহায্য করে। উদাহরণস্বরূপ, THREAD_PRIORITY_DEFAULT একটি থ্রেডের জন্য ডিফল্ট মান উপস্থাপন করে। আপনার অ্যাপের থ্রেডের অগ্রাধিকার THREAD_PRIORITY_BACKGROUND এ সেট করা উচিত যেগুলি কম-জরুরি কাজ সম্পাদন করছে।

আপেক্ষিক অগ্রাধিকার সেট করতে আপনার অ্যাপ THREAD_PRIORITY_LESS_FAVORABLE এবং THREAD_PRIORITY_MORE_FAVORABLE ধ্রুবকগুলিকে ইনক্রিমেন্টার হিসাবে ব্যবহার করতে পারে৷ থ্রেড অগ্রাধিকারের তালিকার জন্য, Process ক্লাসে THREAD_PRIORITY ধ্রুবকগুলি দেখুন।

থ্রেড পরিচালনার বিষয়ে আরও তথ্যের জন্য, Thread এবং Process ক্লাস সম্পর্কে রেফারেন্স ডকুমেন্টেশন দেখুন।

থ্রেডিংয়ের জন্য হেল্পার ক্লাস

বিকাশকারীরা তাদের প্রাথমিক ভাষা হিসাবে Kotlin ব্যবহার করে, আমরা coroutines ব্যবহার করার পরামর্শ দিই। Coroutines কলব্যাক ছাড়া অ্যাসিঙ্ক কোড লেখার পাশাপাশি স্কোপিং, বাতিলকরণ এবং ত্রুটি পরিচালনার জন্য কাঠামোগত সমঝোতা সহ অনেকগুলি সুবিধা প্রদান করে।

ফ্রেমওয়ার্ক একই জাভা ক্লাস এবং আদিম থ্রেডিং সুবিধা প্রদান করে, যেমন Thread , Runnable , এবং Executors ক্লাস, সেইসাথে HandlerThread মতো অতিরিক্ত ক্লাস। আরও তথ্যের জন্য, অনুগ্রহ করে Android এ থ্রেডিং দেখুন।

হ্যান্ডলার থ্রেড ক্লাস

একটি হ্যান্ডলার থ্রেড কার্যকরীভাবে একটি দীর্ঘ-চলমান থ্রেড যা একটি সারি থেকে কাজ দখল করে এবং এটিতে কাজ করে।

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

এই উদাহরণে, যখন আপনার অ্যাপ Camera.open() কমান্ডকে হ্যান্ডলার থ্রেডের কাজের ব্লকে অর্পণ করে, তখন সংশ্লিষ্ট onPreviewFrame() কলব্যাকটি UI থ্রেডের পরিবর্তে হ্যান্ডলার থ্রেডে ল্যান্ড করে। সুতরাং, আপনি যদি পিক্সেলের উপর দীর্ঘস্থায়ী কাজ করতে যাচ্ছেন তবে এটি আপনার জন্য একটি ভাল সমাধান হতে পারে।

যখন আপনার অ্যাপ HandlerThread ব্যবহার করে একটি থ্রেড তৈরি করে, তখন এটি যে ধরনের কাজ করছে তার উপর ভিত্তি করে থ্রেডের অগ্রাধিকার সেট করতে ভুলবেন না। মনে রাখবেন, CPU গুলি সমান্তরালে অল্প সংখ্যক থ্রেড পরিচালনা করতে পারে। অগ্রাধিকার সেট করা সিস্টেমকে এই কাজের সময়সূচী করার সঠিক উপায় জানতে সাহায্য করে যখন অন্যান্য সমস্ত থ্রেড মনোযোগের জন্য লড়াই করছে।

ThreadPoolExecutor ক্লাস

কিছু নির্দিষ্ট ধরণের কাজ রয়েছে যা অত্যন্ত সমান্তরাল, বিতরণ করা কাজগুলিতে হ্রাস করা যেতে পারে। যেমন একটি কাজ, উদাহরণস্বরূপ, একটি 8 মেগাপিক্সেল চিত্রের প্রতিটি 8x8 ব্লকের জন্য একটি ফিল্টার গণনা করা। কাজের প্যাকেটের নিছক পরিমাণের সাথে এটি তৈরি করে, HandlerThread ব্যবহার করার জন্য উপযুক্ত শ্রেণী নয়।

ThreadPoolExecutor এই প্রক্রিয়াটিকে সহজ করার জন্য একটি সহায়ক শ্রেণী। এই শ্রেণীটি থ্রেডের একটি গ্রুপ তৈরি পরিচালনা করে, তাদের অগ্রাধিকার নির্ধারণ করে এবং সেই থ্রেডগুলির মধ্যে কীভাবে কাজ বিতরণ করা হয় তা পরিচালনা করে। কাজের চাপ বাড়তে বা কমলে, কাজের চাপের সাথে সামঞ্জস্য করার জন্য ক্লাসটি আরও থ্রেড ঘোরে বা ধ্বংস করে।

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

আপনি কত থ্রেড তৈরি করা উচিত?

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

কার্যত বলতে গেলে, এর জন্য দায়ী অনেকগুলি ভেরিয়েবল, তবে একটি মান বাছাই করা (যেমন 4, শুরুর জন্য), এবং এটি সিস্ট্রেসের সাথে পরীক্ষা করা অন্য যে কোনও কৌশলের মতোই শক্ত। সমস্যা ছাড়াই আপনি ব্যবহার করতে পারেন এমন ন্যূনতম সংখ্যক থ্রেড আবিষ্কার করতে আপনি ট্রায়াল-এন্ড-এরর ব্যবহার করতে পারেন।

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

অনেক সিস্টেম প্রসেস এবং থার্ড-পার্টি লাইব্রেরি প্রায়ই তাদের নিজস্ব থ্রেডপুল স্পিন আপ করে। যদি আপনার অ্যাপ একটি বিদ্যমান থ্রেডপুল পুনঃব্যবহার করতে পারে, তাহলে এই পুনঃব্যবহার মেমরি এবং প্রসেসিং রিসোর্সের জন্য বিতর্ক কমিয়ে কার্যক্ষমতাকে সাহায্য করতে পারে।