ভাল অনেক ভাল উত্তর, আমি এই আরও যোগ করতে চাই। এটি বুঝতে সাহায্য করবে Extending v/s Implementing Thread
।
দুটি ক্লাসের ফাইলগুলিকে খুব কাছ থেকে বেঁধে দেয় এবং কোড নিয়ে কাজ করার জন্য কিছুটা কঠিন হতে পারে।
উভয় পন্থা একই কাজ করে তবে কিছু পার্থক্য রয়েছে।
সবচেয়ে সাধারণ পার্থক্য হয়
- আপনি যখন থ্রেড ক্লাস প্রসারিত করেন, এর পরে আপনার প্রয়োজন মতো অন্য কোনও শ্রেণি প্রসারিত করতে পারবেন না। (যেমন আপনি জানেন, জাভা একাধিক শ্রেণীর উত্তরাধিকার সূত্রে অনুমতি দেয় না)।
- আপনি যখন রান্নেবল বাস্তবায়ন করেন, ভবিষ্যতে বা এখন অন্য কোনও ক্লাস বাড়ানোর জন্য আপনি আপনার শ্রেণির জন্য স্থান বাঁচাতে পারেন।
যাইহোক, চলমানযোগ্য এবং প্রসারিত থ্রেড বাস্তবায়নের মধ্যে একটি উল্লেখযোগ্য পার্থক্য হ'ল
by extending Thread, each of your threads has a unique object associated with it, whereas implementing Runnable, many threads can share the same object instance.
নিম্নলিখিত উদাহরণটি আপনাকে আরও স্পষ্টভাবে বুঝতে সাহায্য করবে
//Implement Runnable Interface...
class ImplementsRunnable implements Runnable {
private int counter = 0;
public void run() {
counter++;
System.out.println("ImplementsRunnable : Counter : " + counter);
}
}
//Extend Thread class...
class ExtendsThread extends Thread {
private int counter = 0;
public void run() {
counter++;
System.out.println("ExtendsThread : Counter : " + counter);
}
}
//Use the above classes here in main to understand the differences more clearly...
public class ThreadVsRunnable {
public static void main(String args[]) throws Exception {
// Multiple threads share the same object.
ImplementsRunnable rc = new ImplementsRunnable();
Thread t1 = new Thread(rc);
t1.start();
Thread.sleep(1000); // Waiting for 1 second before starting next thread
Thread t2 = new Thread(rc);
t2.start();
Thread.sleep(1000); // Waiting for 1 second before starting next thread
Thread t3 = new Thread(rc);
t3.start();
// Creating new instance for every thread access.
ExtendsThread tc1 = new ExtendsThread();
tc1.start();
Thread.sleep(1000); // Waiting for 1 second before starting next thread
ExtendsThread tc2 = new ExtendsThread();
tc2.start();
Thread.sleep(1000); // Waiting for 1 second before starting next thread
ExtendsThread tc3 = new ExtendsThread();
tc3.start();
}
}
উপরের প্রোগ্রামটির আউটপুট।
ImplementsRunnable : Counter : 1
ImplementsRunnable : Counter : 2
ImplementsRunnable : Counter : 3
ExtendsThread : Counter : 1
ExtendsThread : Counter : 1
ExtendsThread : Counter : 1
চলমানযোগ্য ইন্টারফেস পদ্ধতির মধ্যে একটি শ্রেণীর কেবলমাত্র একটি উদাহরণ তৈরি করা হচ্ছে এবং এটি বিভিন্ন থ্রেড দ্বারা ভাগ করা হয়েছে। সুতরাং প্রতিটি থ্রেড অ্যাক্সেসের জন্য কাউন্টারটির মান বাড়ানো হয়।
যেখানে থ্রেড ক্লাসের অ্যাপ্রোচ, আপনাকে অবশ্যই প্রতিটি থ্রেড অ্যাক্সেসের জন্য পৃথক উদাহরণ তৈরি করতে হবে। সুতরাং প্রতিটি শ্রেণীর উদাহরণগুলির জন্য পৃথক মেমরি বরাদ্দ করা হয় এবং প্রত্যেকের পৃথক কাউন্টার থাকে, মান একই থাকে, যার অর্থ কোনও বর্ধন ঘটবে না কারণ কোনও বস্তুর রেফারেন্স একই নয়।
রান্নেবল কখন ব্যবহার করবেন?
আপনি যখন থ্রেডের গোষ্ঠী থেকে একই সংস্থানগুলি অ্যাক্সেস করতে চান তখন রানবেল ইন্টারফেস ব্যবহার করুন। এখানে থ্রেড ক্লাস ব্যবহার করা এড়িয়ে চলুন, কারণ একাধিক অবজেক্ট তৈরি আরও মেমরি গ্রহণ করে এবং এটি ওভারহেডে একটি বড় পারফরম্যান্স হয়ে যায়।
একটি ক্লাস যা রান্নেবল প্রয়োগ করে তা কোনও থ্রেড নয় এবং কেবল একটি শ্রেণি। একটি রান্নেবলকে থ্রেডে পরিণত হওয়ার জন্য আপনাকে থ্রেডের একটি উদাহরণ তৈরি করতে হবে এবং লক্ষ্য হিসাবে নিজেকে এড়িয়ে চলতে হবে।
বেশিরভাগ ক্ষেত্রে, রান্নেবল ইন্টারফেসটি ব্যবহার করা উচিত যদি আপনি কেবল ওভাররাইড করার পরিকল্পনা করছেন run()
পদ্ধতিটি এবং অন্য কোনও থ্রেড পদ্ধতি নেই। এটি গুরুত্বপূর্ণ কারণ প্রোগ্রামার ক্লাসের মৌলিক আচরণটি সংশোধন বা উন্নত করতে না চাইলে ক্লাসগুলি সাবক্ল্যাস করা উচিত নয়।
যখন একটি সুপারক্লাস প্রসারিত করার প্রয়োজন হয় তখন থ্রেড ক্লাস ব্যবহার করার চেয়ে রান্নেবল ইন্টারফেস প্রয়োগ করা আরও উপযুক্ত। কারণ আমরা থ্রেড তৈরির জন্য রান্নেবল ইন্টারফেস প্রয়োগ করার সময় অন্য শ্রেণি প্রসারিত করতে পারি।
আমি আশা করি এটি সাহায্য করবে!