মাল্টিথ্রেডিং দ্বারা সমস্যার সমাধান
মাল্টিথ্রেডিং আসলে দুটি গুরুত্বপূর্ণ উদ্দেশ্য অর্জনের জন্য উদ্ভাবিত হয়েছিল:-
একই সময়ে বেশ কয়েকটি কাজ করুন।
উপরের উদাহরণে, বিভিন্ন থ্রেড (পরিবারের সদস্যরা) সমান্তরালভাবে বেশ কয়েকটি ক্রিয়া সম্পাদন করেছে: তারা থালা-বাসন ধুয়েছে, দোকানে গেছে এবং জিনিসপত্র প্যাক করেছে।
আমরা প্রোগ্রামিংয়ের সাথে আরও ঘনিষ্ঠভাবে সম্পর্কিত একটি উদাহরণ দিতে পারি। ধরুন আপনার একটি ইউজার ইন্টারফেস সহ একটি প্রোগ্রাম আছে। আপনি যখন প্রোগ্রামে 'চালিয়ে যান' ক্লিক করেন, তখন কিছু গণনা হওয়া উচিত এবং ব্যবহারকারীকে নিম্নলিখিত স্ক্রীনটি দেখতে হবে। যদি এই ক্রিয়াগুলি ক্রমানুসারে সম্পাদিত হয়, তাহলে ব্যবহারকারী 'চালিয়ে যান' বোতামে ক্লিক করার পরে প্রোগ্রামটি হ্যাং হয়ে যাবে। ব্যবহারকারী 'চালিয়ে যান' বোতামের স্ক্রীনটি দেখতে পাবেন যতক্ষণ না প্রোগ্রামটি সমস্ত অভ্যন্তরীণ গণনা সম্পাদন করে এবং ব্যবহারকারীর ইন্টারফেসটি রিফ্রেশ করা অংশে পৌঁছায়।
ঠিক আছে, আমি অনুমান করি আমরা কয়েক মিনিট অপেক্ষা করব!
অথবা আমরা আমাদের প্রোগ্রাম পুনরায় কাজ করতে পারে, অথবা, প্রোগ্রামাররা বলে, এটি 'সমান্তরাল'। আসুন একটি থ্রেডে আমাদের গণনা করি এবং অন্যটিতে ইউজার ইন্টারফেস আঁকি। বেশিরভাগ কম্পিউটারে এটি করার জন্য যথেষ্ট সংস্থান রয়েছে। যদি আমরা এই রুটটি গ্রহণ করি, তাহলে প্রোগ্রামটি জমে যাবে না এবং ব্যবহারকারী ভিতরে কী ঘটছে তা নিয়ে চিন্তা না করেই স্ক্রিনের মধ্যে মসৃণভাবে চলে যাবে। একটি অন্যের সাথে হস্তক্ষেপ করে না :)
-
আরো দ্রুত গণনা সঞ্চালন.
এখানে সবকিছু অনেক সহজ। যদি আমাদের প্রসেসরের একাধিক কোর থাকে, এবং বেশিরভাগ প্রসেসর আজ তা করে, তাহলে বেশ কয়েকটি কোর আমাদের কাজের তালিকা সমান্তরালভাবে পরিচালনা করতে পারে। স্পষ্টতই, যদি আমাদের 1000টি কাজ সম্পাদন করতে হয় এবং প্রতিটিতে এক সেকেন্ড সময় লাগে, একটি কোর 1000 সেকেন্ডে তালিকাটি শেষ করতে পারে, দুটি কোর 500 সেকেন্ডে, তিনটি 333 সেকেন্ডের কিছু বেশি সময়ের মধ্যে, ইত্যাদি।
public class MyFirstThread extends Thread {
@Override
public void run() {
System.out.println("I'm Thread! My name is " + getName());
}
}
থ্রেড তৈরি এবং চালানোর জন্য, আমাদের একটি ক্লাস তৈরি করতে হবে, এটিকে java.lang- এর উত্তরাধিকারী করতে হবে । থ্রেড ক্লাস, এবং এর রান() পদ্ধতি ওভাররাইড করুন। যে শেষ প্রয়োজন খুবই গুরুত্বপূর্ণ. এটি রান() পদ্ধতিতে আমরা আমাদের থ্রেড চালানোর জন্য যুক্তি সংজ্ঞায়িত করি। এখন, যদি আমরা MyFirstThread- এর একটি উদাহরণ তৈরি এবং চালাই , রান() পদ্ধতি একটি নামের একটি লাইন প্রদর্শন করবে: getName() পদ্ধতিটি থ্রেডের 'সিস্টেম' নাম প্রদর্শন করে, যা স্বয়ংক্রিয়ভাবে নির্ধারিত হয়। কিন্তু কেন আমরা অস্থায়ীভাবে কথা বলছি? এর একটি তৈরি করা যাক এবং খুঁজে বের করা যাক!
public class Main {
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
MyFirstThread thread = new MyFirstThread();
thread.start();
}
}
}
কনসোল আউটপুট: আমি থ্রেড! আমার নাম থ্রেড-২ আমি থ্রেড! আমার নাম থ্রেড-১ আমি থ্রেড! আমার নাম থ্রেড-০ আমি থ্রেড! আমার নাম থ্রেড-৩ আমি থ্রেড! আমার নাম থ্রেড-৬ আমি থ্রেড! আমার নাম থ্রেড-৭ আমি থ্রেড! আমার নাম থ্রেড-৪ আমি থ্রেড! আমার নাম থ্রেড-৫ আমি থ্রেড! আমার নাম থ্রেড-9 আমি থ্রেড! My name is Thread-8 আসুন 10টি থ্রেড তৈরি করি ( MyFirstThread অবজেক্ট, যা থ্রেড ইনহেরিট করে ) এবং প্রতিটি অবজেক্টে start() মেথড কল করে শুরু করি। start() মেথড কল করার পর রান() মেথডের লজিক এক্সিকিউট করা হয়। দ্রষ্টব্য: থ্রেড নামগুলি ক্রমানুসারে নয়। এটা অদ্ভুত যে তারা ক্রমানুসারে ছিল না:, থ্রেড -1 , থ্রেড -2 , এবং তাই? এটি যেমন ঘটে, এটি এমন একটি সময়ের উদাহরণ যখন 'অনুক্রমিক' চিন্তা ফিট হয় না। সমস্যা হল যে আমরা শুধুমাত্র 10টি থ্রেড তৈরি এবং চালানোর জন্য কমান্ড প্রদান করেছি। থ্রেড শিডিউলার, একটি বিশেষ অপারেটিং সিস্টেম মেকানিজম, তাদের কার্যকর করার আদেশ নির্ধারণ করে। এর সুনির্দিষ্ট নকশা এবং সিদ্ধান্ত নেওয়ার কৌশল হল একটি গভীর আলোচনার বিষয় যা আমরা এখনই ডুবে দেব না। মনে রাখা প্রধান জিনিস হল যে প্রোগ্রামার থ্রেডের এক্সিকিউশন অর্ডার নিয়ন্ত্রণ করতে পারে না। পরিস্থিতির গুরুতরতা বোঝার জন্য, উপরের উদাহরণে main() পদ্ধতিটি আরও কয়েকবার চালানোর চেষ্টা করুন। দ্বিতীয় রানে কনসোল আউটপুট: আমি থ্রেড! আমার নাম থ্রেড-০ আমি থ্রেড! আমার নাম থ্রেড-৪ আমি থ্রেড! আমার নাম থ্রেড-৩ আমি থ্রেড! আমার নাম থ্রেড-২ আমি থ্রেড! আমার নাম থ্রেড-১ আমি থ্রেড! আমার নাম থ্রেড-৫ আমি থ্রেড! আমার নাম থ্রেড-৬ আমি থ্রেড! আমার নাম থ্রেড-8 আমি থ্রেড! আমার নাম থ্রেড-9 আমি থ্রেড! আমার নাম তৃতীয় রান থেকে থ্রেড-7 কনসোল আউটপুট: আমি থ্রেড! আমার নাম থ্রেড-০ আমি থ্রেড! আমার নাম থ্রেড-৩ আমি থ্রেড! আমার নাম থ্রেড-১ আমি থ্রেড! আমার নাম থ্রেড-২ আমি থ্রেড! আমার নাম থ্রেড-৬ আমি থ্রেড! আমার নাম থ্রেড-৪ আমি থ্রেড! আমার নাম থ্রেড-9 আমি থ্রেড! আমার নাম থ্রেড-৫ আমি থ্রেড! আমার নাম থ্রেড-৭ আমি থ্রেড! আমার নাম থ্রেড-8
মাল্টিথ্রেডিং দ্বারা তৈরি সমস্যা
বইগুলির সাথে আমাদের উদাহরণে, আপনি দেখেছেন যে মাল্টিথ্রেডিং খুব গুরুত্বপূর্ণ কাজগুলি সমাধান করে এবং আমাদের প্রোগ্রামগুলিকে দ্রুততর করতে পারে। প্রায়শই অনেক গুণ দ্রুত। কিন্তু মাল্টিথ্রেডিং একটি কঠিন বিষয় বলে মনে করা হয়। প্রকৃতপক্ষে, যদি ভুলভাবে ব্যবহার করা হয়, এটি তাদের সমাধানের পরিবর্তে সমস্যা তৈরি করে। যখন আমি বলি 'সমস্যা তৈরি করে', আমি কিছু বিমূর্ত অর্থে বোঝাতে চাই না। দুটি নির্দিষ্ট সমস্যা রয়েছে যা মাল্টিথ্রেডিং তৈরি করতে পারে: অচলাবস্থা এবং রেসের অবস্থা। অচলাবস্থা হল এমন একটি পরিস্থিতি যেখানে একাধিক থ্রেড একে অপরের দ্বারা ধারণ করা সংস্থানগুলির জন্য অপেক্ষা করছে এবং তাদের কেউই চলতে পারে না। আমরা পরবর্তী পাঠে এটি সম্পর্কে আরও কথা বলব। নিম্নলিখিত উদাহরণটি আপাতত যথেষ্ট হবে:
- থ্রেড-১ অবজেক্ট-১-এর সাথে ইন্টারঅ্যাক্ট করা বন্ধ করে এবং অবজেক্ট-২-এ স্যুইচ করে যখন থ্রেড-২ অবজেক্ট-২-এর সঙ্গে ইন্টারঅ্যাক্ট করা বন্ধ করে এবং অবজেক্ট-১-এ স্যুইচ করে।
- থ্রেড-২ অবজেক্ট-২-এর সাথে ইন্টারঅ্যাক্ট করা বন্ধ করে এবং অবজেক্ট-১-এ স্যুইচ করে যখন থ্রেড-১ অবজেক্ট-১-এর সঙ্গে ইন্টারঅ্যাক্ট করা বন্ধ করে এবং অবজেক্ট-২-এ স্যুইচ করে।
public class MyFirstThread extends Thread {
@Override
public void run() {
System.out.println("Thread executed: " + getName());
}
}
public class Main {
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
MyFirstThread thread = new MyFirstThread();
thread.start();
}
}
}
এখন কল্পনা করুন যে প্রোগ্রামটি একটি রোবট চালানোর জন্য দায়ী যা খাবার রান্না করে! থ্রেড-০ ফ্রিজ থেকে ডিম বের করে। থ্রেড-1 চুলা চালু। থ্রেড-২ একটি প্যান পায় এবং চুলায় রাখে। থ্রেড-৩ চুলা জ্বালায়। থ্রেড-4 প্যানে তেল ঢেলে দেয়। থ্রেড-5 ডিম ভেঙে প্যানে ঢেলে দেয়। থ্রেড-6 ডিমের খোসাগুলোকে ট্র্যাশে ফেলে দেয়। থ্রেড -7 বার্নার থেকে রান্না করা ডিম সরিয়ে দেয়। থ্রেড -8 একটি প্লেটে রান্না করা ডিম রাখে। থ্রেড-9 থালা-বাসন ধুয়ে দেয়। আমাদের প্রোগ্রামের ফলাফল দেখুন: থ্রেড কার্যকর করা হয়েছে: থ্রেড-0 থ্রেড কার্যকর করা হয়েছে: থ্রেড-2 থ্রেড নির্বাহিত থ্রেড-1 থ্রেড কার্যকর করা হয়েছে: থ্রেড-4 থ্রেড কার্যকর করা হয়েছে: থ্রেড-9 থ্রেড কার্যকর করা হয়েছে: থ্রেড-5 থ্রেড কার্যকর করা হয়েছে: থ্রেড-8 থ্রেড নির্বাহিত: থ্রেড-7 থ্রেড কার্যকর করা হয়েছে: থ্রেড-3 এটা কি কমেডি রুটিন? :) এবং সব কারণ আমাদের প্রোগ্রামের কাজ থ্রেডের এক্সিকিউশন অর্ডারের উপর নির্ভর করে। প্রয়োজনীয় ক্রমটির সামান্য লঙ্ঘন করা হলে, আমাদের রান্নাঘর নরকে পরিণত হয় এবং একটি উন্মাদ রোবট তার চারপাশের সবকিছু ধ্বংস করে দেয়। এটি মাল্টিথ্রেডেড প্রোগ্রামিং-এ একটি সাধারণ সমস্যা। আপনি এটি সম্পর্কে একাধিকবার শুনতে পাবেন। এই পাঠটি শেষ করার জন্য, আমি মাল্টিথ্রেডিং সম্পর্কে একটি বই সুপারিশ করতে চাই। 
GO TO FULL VERSION