Java Executor Framework হলো একটি শক্তিশালী টুল যা সহজে এবং কার্যকরভাবে থ্রেড ম্যানেজমেন্ট এবং কনকারেন্ট টাস্কগুলি পরিচালনা করতে ব্যবহৃত হয়। এটি জাভার java.util.concurrent প্যাকেজে অন্তর্ভুক্ত।
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ExecutorExample {
public static void main(String[] args) {
ExecutorService executor = Executors.newFixedThreadPool(3);
Runnable task = () -> {
System.out.println(Thread.currentThread().getName() + " is executing a task.");
};
// ৫টি টাস্ক সাবমিট করা
for (int i = 0; i < 5; i++) {
executor.submit(task);
}
executor.shutdown(); // Executor বন্ধ করা
}
}
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class ScheduledExecutorExample {
public static void main(String[] args) {
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
Runnable task = () -> {
System.out.println("Task executed at: " + System.currentTimeMillis());
};
// প্রতি ২ সেকেন্ড অন্তর টাস্ক চালানো
scheduler.scheduleAtFixedRate(task, 0, 2, TimeUnit.SECONDS);
// ১০ সেকেন্ড পর Scheduler বন্ধ করা
scheduler.schedule(() -> scheduler.shutdown(), 10, TimeUnit.SECONDS);
}
}
Callable ইন্টারফেস ব্যবহার করে টাস্ক থেকে একটি ফলাফল ফেরত পাওয়া সম্ভব।
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class CallableFutureExample {
public static void main(String[] args) throws Exception {
ExecutorService executor = Executors.newSingleThreadExecutor();
Callable<Integer> task = () -> {
System.out.println("Performing a computation...");
Thread.sleep(2000); // স্লিপ
return 123; // ফলাফল ফেরত
};
Future<Integer> future = executor.submit(task);
System.out.println("Task submitted. Waiting for result...");
// Future থেকে ফলাফল পাওয়া
Integer result = future.get();
System.out.println("Result: " + result);
executor.shutdown();
}
}
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class CustomThreadPoolExample {
public static void main(String[] args) {
ThreadPoolExecutor threadPool = new ThreadPoolExecutor(
2, // Core pool size
4, // Maximum pool size
1, // Keep alive time
TimeUnit.MINUTES,
new LinkedBlockingQueue<>(2) // Task queue
);
Runnable task = () -> {
System.out.println(Thread.currentThread().getName() + " is executing a task.");
};
for (int i = 0; i < 6; i++) {
threadPool.execute(task);
}
threadPool.shutdown();
}
}
shutdown()
: থ্রেড পুলে আর নতুন টাস্ক নেওয়া হবে না। চলমান টাস্কগুলি শেষ হবে।shutdownNow()
: চলমান টাস্কগুলি বন্ধ করার চেষ্টা করে এবং টাস্কের কিউতে থাকা সব টাস্ক বাতিল করে।executor.shutdown();
if (!executor.awaitTermination(60, TimeUnit.SECONDS)) {
executor.shutdownNow();
}
Executor বন্ধ হওয়ার পরে এটি শেষ হতে নির্দিষ্ট সময় পর্যন্ত অপেক্ষা করে।
আপনার প্রয়োজন অনুযায়ী Executor Framework এর সঠিক ক্লাস এবং পদ্ধতি নির্বাচন করুন।
Executor Framework হল জাভার একটি শক্তিশালী টুল যা মাল্টি-থ্রেডেড প্রোগ্রামিং সহজ করে। এটি java.util.concurrent প্যাকেজে অন্তর্ভুক্ত এবং থ্রেড তৈরি, শিডিউলিং, এবং ব্যবস্থাপনার জন্য উন্নত API সরবরাহ করে। Executor Framework ম্যানুয়াল থ্রেড ম্যানেজমেন্টের তুলনায় আরও দক্ষ ও নির্ভরযোগ্য।
মাল্টি-থ্রেডিং প্রোগ্রামে সরাসরি Thread
ক্লাস ব্যবহার করে নতুন থ্রেড তৈরি করা জটিল হতে পারে। Executor Framework এ কাজের জন্য থ্রেড তৈরির পরিবর্তে একটি থ্রেড পুল ব্যবহার করা হয়, যা নিম্নলিখিত সুবিধা প্রদান করে:
Executor Framework তিনটি মূল ইন্টারফেস নিয়ে গঠিত:
execute()
মেথড সরবরাহ করে।উদাহরণ:
Executor executor = Runnable::run;
executor.execute(() -> System.out.println("Task executed"));
submit()
এবং shutdown()
এর মতো মেথড প্রদান করে।উদাহরণ:
ExecutorService executorService = Executors.newFixedThreadPool(3);
executorService.submit(() -> System.out.println("Task submitted"));
executorService.shutdown();
উদাহরণ:
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(2);
scheduler.schedule(() -> System.out.println("Task executed after delay"), 3, TimeUnit.SECONDS);
scheduler.shutdown();
Executor Framework ব্যবহার করার জন্য জাভা কিছু স্ট্যাটিক মেথড এবং ক্লাস সরবরাহ করে। এর মধ্যে উল্লেখযোগ্য:
newFixedThreadPool(int nThreads)
: একটি নির্দিষ্ট সংখ্যা থ্রেড পুল তৈরি করে।newCachedThreadPool()
: একটি ডায়নামিক থ্রেড পুল তৈরি করে।newSingleThreadExecutor()
: একক থ্রেডের পুল তৈরি করে।newScheduledThreadPool(int corePoolSize)
: সময়সূচি অনুযায়ী টাস্ক পরিচালনা করে।import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class FixedThreadPoolExample {
public static void main(String[] args) {
ExecutorService executor = Executors.newFixedThreadPool(3);
for (int i = 1; i <= 5; i++) {
int taskId = i;
executor.submit(() -> {
System.out.println("Task " + taskId + " is running on thread: " + Thread.currentThread().getName());
});
}
executor.shutdown();
}
}
আউটপুট (সম্ভাব্য):
Task 1 is running on thread: pool-1-thread-1
Task 2 is running on thread: pool-1-thread-2
Task 3 is running on thread: pool-1-thread-3
Task 4 is running on thread: pool-1-thread-1
Task 5 is running on thread: pool-1-thread-2
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class CachedThreadPoolExample {
public static void main(String[] args) {
ExecutorService executor = Executors.newCachedThreadPool();
for (int i = 1; i <= 5; i++) {
int taskId = i;
executor.submit(() -> {
System.out.println("Task " + taskId + " is running on thread: " + Thread.currentThread().getName());
});
}
executor.shutdown();
}
}
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class ScheduledExecutorExample {
public static void main(String[] args) {
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(2);
scheduler.schedule(() -> System.out.println("Task executed after 5 seconds"), 5, TimeUnit.SECONDS);
scheduler.scheduleAtFixedRate(() -> System.out.println("Periodic Task"), 1, 3, TimeUnit.SECONDS);
scheduler.scheduleWithFixedDelay(() -> System.out.println("Task with delay"), 1, 2, TimeUnit.SECONDS);
try {
Thread.sleep(10000); // Wait for 10 seconds to observe tasks
} catch (InterruptedException e) {
e.printStackTrace();
}
scheduler.shutdown();
}
}
shutdown()
ব্যবহার করুন: Executor Service শেষ হওয়ার পরে এটি বন্ধ করুন।FixedThreadPool
, CachedThreadPool
বা ScheduledThreadPool
ব্যবহার করুন।Executor Framework মাল্টি-থ্রেডেড প্রোগ্রামিংয়ের জটিলতা অনেকাংশে দূর করে এবং স্কেলেবল এবং দক্ষ অ্যাপ্লিকেশন তৈরির জন্য একটি শক্তিশালী টুলসেট সরবরাহ করে। এটি জাভা প্রোগ্রামিংয়ে কনকারেন্সি সহজ ও আরও কার্যকর করে।
Thread Pooling হলো একটি কনকারেন্সি মডেল যেখানে একাধিক থ্রেড একটি থ্রেড পুলে তৈরি এবং পুনরায় ব্যবহার করা হয়। নতুন থ্রেড তৈরি এবং ধ্বংস করার পরিবর্তে, থ্রেডগুলো পুনর্ব্যবহার করে কার্যক্ষমতা বৃদ্ধি করা হয়।
java.util.concurrent
প্যাকেজের Executor Framework এই থ্রেড পুলিং মেকানিজমকে সহজতর এবং কার্যকর করেছে।
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ThreadPoolingExample {
public static void main(String[] args) {
// একটি Fixed Thread Pool তৈরি
ExecutorService executorService = Executors.newFixedThreadPool(3);
// Task তৈরি
Runnable task = () -> {
System.out.println(Thread.currentThread().getName() + " is executing the task.");
try {
Thread.sleep(1000); // কাজ সম্পন্ন করার জন্য সাময়িক বিরতি
} catch (InterruptedException e) {
e.printStackTrace();
}
};
// পুলে Task জমা দিন
for (int i = 0; i < 10; i++) {
executorService.execute(task);
}
// পুল বন্ধ করুন
executorService.shutdown();
}
}
pool-1-thread-1 is executing the task.
pool-1-thread-2 is executing the task.
pool-1-thread-3 is executing the task.
...
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class CachedThreadPoolExample {
public static void main(String[] args) {
// একটি Cached Thread Pool তৈরি
ExecutorService executorService = Executors.newCachedThreadPool();
// Task তৈরি
Runnable task = () -> {
System.out.println(Thread.currentThread().getName() + " is executing the task.");
};
// পুলে Task জমা দিন
for (int i = 0; i < 5; i++) {
executorService.execute(task);
}
// পুল বন্ধ করুন
executorService.shutdown();
}
}
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class SingleThreadExecutorExample {
public static void main(String[] args) {
// একটি Single Thread Executor তৈরি
ExecutorService executorService = Executors.newSingleThreadExecutor();
// Task তৈরি
Runnable task = () -> {
System.out.println(Thread.currentThread().getName() + " is executing the task.");
};
// পুলে Task জমা দিন
for (int i = 0; i < 3; i++) {
executorService.execute(task);
}
// পুল বন্ধ করুন
executorService.shutdown();
}
}
Future
বা Callable
ব্যবহার করুন।Thread Pooling জাভা কনকারেন্সির একটি শক্তিশালী টুল যা অ্যাপ্লিকেশনের কার্যক্ষমতা বাড়াতে গুরুত্বপূর্ণ ভূমিকা পালন করে। এটি সিস্টেম রিসোর্সের সঠিক ব্যবহার নিশ্চিত করে এবং থ্রেড ম্যানেজমেন্ট সহজতর করে। তবে, যথাযথ ডিজাইন এবং সীমাবদ্ধতা বিবেচনা করে এটি ব্যবহার করা উচিত।
FixedThreadPool
এবং CachedThreadPool
হল Java Concurrency এর ExecutorService
ইন্টারফেসের দুটি গুরুত্বপূর্ণ থ্রেড পুল। এগুলো থ্রেড ম্যানেজমেন্ট আরও কার্যকর করতে ব্যবহৃত হয়।
FixedThreadPool
একটি নির্দিষ্ট সংখ্যক থ্রেড নিয়ে কাজ করে।
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class FixedThreadPoolExample {
public static void main(String[] args) {
// ১. FixedThreadPool তৈরি (3 থ্রেড)
ExecutorService executor = Executors.newFixedThreadPool(3);
for (int i = 1; i <= 10; i++) {
final int taskId = i;
executor.execute(() -> {
System.out.println("Task " + taskId + " is running on thread " + Thread.currentThread().getName());
try {
Thread.sleep(2000); // প্রতিটি টাস্ক ২ সেকেন্ড সময় নেয়
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
});
}
// ExecutorService বন্ধ করুন
executor.shutdown();
}
}
আউটপুট:
CachedThreadPool
এর থ্রেড সংখ্যা ডায়নামিক।
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class CachedThreadPoolExample {
public static void main(String[] args) {
// ১. CachedThreadPool তৈরি
ExecutorService executor = Executors.newCachedThreadPool();
for (int i = 1; i <= 10; i++) {
final int taskId = i;
executor.execute(() -> {
System.out.println("Task " + taskId + " is running on thread " + Thread.currentThread().getName());
try {
Thread.sleep(2000); // প্রতিটি টাস্ক ২ সেকেন্ড সময় নেয়
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
});
}
// ExecutorService বন্ধ করুন
executor.shutdown();
}
}
আউটপুট:
প্যারামিটার | FixedThreadPool | CachedThreadPool |
---|---|---|
থ্রেড সংখ্যা | নির্দিষ্ট (Fixed) | ডায়নামিক (প্রয়োজন অনুযায়ী তৈরি এবং ধ্বংস) |
কর্মক্ষমতা (Performance) | কম টাস্ক থাকলে দ্রুত এবং নিয়ন্ত্রিত | বেশি টাস্কে দ্রুত (প্রচুর থ্রেড তৈরি হতে পারে) |
রিসোর্স ব্যবহারে নিয়ন্ত্রণ | থ্রেড সংখ্যা নিয়ন্ত্রিত | রিসোর্স বেশি ব্যবহৃত হতে পারে |
ব্যবহার ক্ষেত্র | সীমিত এবং পূর্ব নির্ধারিত টাস্ক | ডায়নামিক এবং অপ্রত্যাশিত টাস্ক |
FixedThreadPool
ব্যবহার করুন, যদি থ্রেড সংখ্যা পূর্বনির্ধারিত থাকে এবং সিস্টেম রিসোর্স নিয়ন্ত্রণে রাখতে চান।CachedThreadPool
ব্যবহার করুন, যদি টাস্ক সংখ্যা ডায়নামিক হয় এবং দ্রুত থ্রেড তৈরি করার প্রয়োজন হয়।এই উদাহরণগুলো দেখে আপনি FixedThreadPool এবং CachedThreadPool এর কাজ এবং তাদের মধ্যে পার্থক্য বুঝতে পারবেন।
Callable
এবং Future
ইন্টারফেস জাভাতে মাল্টি-থ্রেডিংয়ের জন্য ব্যবহৃত হয় এবং সিঙ্ক্রোনাস বা অ্যাসিঙ্ক্রোনাস টাস্ক সম্পাদনে সাহায্য করে। এদের সাহায্যে থ্রেড থেকে ডেটা ফেরত পাওয়া এবং থ্রেডের এক্সিকিউশন স্টেট পরিচালনা করা সম্ভব।
java.util.concurrent
প্যাকেজের একটি ইন্টারফেস যা একটি রিটার্ন ভ্যালু এবং এক্সসেপশন থ্রো করার ক্ষমতা প্রদান করে।Runnable
এর বিকল্প যা কোনো রিটার্ন ভ্যালু দেয় না।call()
মেথড ব্যবহার করে কাজ করে।import java.util.concurrent.Callable;
class MyCallableTask implements Callable<Integer> {
@Override
public Integer call() throws Exception {
System.out.println("Callable Task Executing...");
return 42; // রিটার্ন ভ্যালু
}
}
get()
: টাস্ক শেষ হলে রিটার্ন ভ্যালু প্রদান করে। এটি ব্লকিং।isDone()
: টাস্ক শেষ হয়েছে কিনা তা জানায়।isCancelled()
: টাস্ক বাতিল হয়েছে কিনা তা জানায়।cancel(boolean mayInterruptIfRunning)
: টাস্ক বাতিল করে।import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class CallableFutureExample {
public static void main(String[] args) {
// ১. ExecutorService তৈরি করুন
ExecutorService executor = Executors.newSingleThreadExecutor();
// ২. Callable টাস্ক তৈরি করুন
Callable<Integer> task = () -> {
System.out.println("Callable Task Executing...");
Thread.sleep(2000); // কিছু সময় অপেক্ষা
return 42; // রিটার্ন ভ্যালু
};
// ৩. Future ব্যবহার করে টাস্ক জমা দিন
Future<Integer> future = executor.submit(task);
// ৪. টাস্কের স্টেট চেক করুন
System.out.println("Task Submitted. Waiting for result...");
try {
// রিটার্ন ভ্যালু পান
Integer result = future.get(); // ব্লকিং মেথড
System.out.println("Result from Callable: " + result);
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
// ৫. Executor বন্ধ করুন
executor.shutdown();
}
}
আউটপুট:
Callable Task Executing...
Task Submitted. Waiting for result...
Result from Callable: 42
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class FutureCancelExample {
public static void main(String[] args) {
ExecutorService executor = Executors.newSingleThreadExecutor();
Callable<String> task = () -> {
Thread.sleep(5000); // ৫ সেকেন্ডের জন্য স্লিপ
return "Task Completed!";
};
Future<String> future = executor.submit(task);
try {
// টাস্ক বাতিল করার আগে কিছুক্ষণ অপেক্ষা করুন
Thread.sleep(2000);
System.out.println("Cancelling the task...");
future.cancel(true); // টাস্ক বাতিল
// টাস্ক স্টেট চেক করুন
if (future.isCancelled()) {
System.out.println("Task was cancelled.");
} else {
System.out.println("Result: " + future.get());
}
} catch (Exception e) {
e.printStackTrace();
} finally {
executor.shutdown();
}
}
}
আউটপুট:
Cancelling the task...
Task was cancelled.
get()
মেথড ব্লকিং, যা কার্যক্ষমতা হ্রাস করতে পারে।FutureTask
হলো Callable এবং Future এর একটি ইমপ্লিমেন্টেশন। এটি সরাসরি ব্যবহার করা যায়।
import java.util.concurrent.FutureTask;
public class FutureTaskExample {
public static void main(String[] args) {
// FutureTask তৈরি
FutureTask<Integer> futureTask = new FutureTask<>(() -> {
Thread.sleep(3000);
return 100;
});
// FutureTask রান করান
Thread thread = new Thread(futureTask);
thread.start();
try {
System.out.println("Waiting for result...");
System.out.println("Result: " + futureTask.get());
} catch (Exception e) {
e.printStackTrace();
}
}
}
আউটপুট:
Waiting for result...
Result: 100
এই টুলগুলো ব্যবহার করে জাভাতে মাল্টি-থ্রেডিংয়ের কার্যকারিতা এবং নমনীয়তা বাড়ানো যায়।
Read more