Callable এবং Runnable ইন্টারফেস দুটোই জাভাতে কনকারেন্ট টাস্ক কার্যকর করার জন্য ব্যবহৃত হয়। তবে, তাদের মধ্যে কিছু গুরুত্বপূর্ণ পার্থক্য রয়েছে।
Runnable Interface
- রিটার্ন ভ্যালু নেই:
Runnableইন্টারফেস কোনো রিটার্ন ভ্যালু দেয় না।run()মেথড কেবল একটি টাস্ক সম্পন্ন করে। - চলতি থ্রেডে এক্সিকিউট হয়:
RunnableসরাসরিThreadক্লাস বাExecutorServiceদ্বারা চালানো হয়। - Exception Handling নেই:
run()মেথড চেকড এক্সেপশন থ্রো করতে পারে না। - ব্যবহার: সাধারণত হালকা কাজ সম্পাদনের জন্য ব্যবহার করা হয়।
Runnable উদাহরণ:
class MyRunnable implements Runnable {
@Override
public void run() {
System.out.println("Runnable is running: " + Thread.currentThread().getName());
}
}
public class RunnableExample {
public static void main(String[] args) {
Runnable myRunnable = new MyRunnable();
Thread thread = new Thread(myRunnable);
thread.start();
}
}
Callable Interface
- রিটার্ন ভ্যালু দেয়:
Callableইন্টারফেস একটি রিটার্ন ভ্যালু প্রদান করে। এটিcall()মেথড ব্যবহার করে। - Future অবজেক্টের মাধ্যমে রিটার্ন:
Callable-এর রিটার্ন ভ্যালুFutureঅবজেক্টের মাধ্যমে অ্যাক্সেস করা যায়। - Exception Handling সমর্থন করে:
call()মেথড চেকড এক্সেপশন থ্রো করতে পারে। - ব্যবহার: কমপ্লেক্স বা দীর্ঘমেয়াদী কাজ যেখানে রিটার্ন ভ্যালু প্রয়োজন হয়।
Callable উদাহরণ:
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
class MyCallable implements Callable<String> {
@Override
public String call() throws Exception {
Thread.sleep(1000); // কিছু কাজ করছে
return "Callable completed by: " + Thread.currentThread().getName();
}
}
public class CallableExample {
public static void main(String[] args) {
ExecutorService executor = Executors.newSingleThreadExecutor();
Callable<String> myCallable = new MyCallable();
Future<String> future = executor.submit(myCallable);
try {
System.out.println("Result: " + future.get()); // Future থেকে ফলাফল পেতে
} catch (Exception e) {
e.printStackTrace();
} finally {
executor.shutdown();
}
}
}
Callable এবং Runnable-এর মধ্যে পার্থক্য
| বৈশিষ্ট্য | Runnable | Callable |
|---|---|---|
| রিটার্ন ভ্যালু | না (void) | হ্যাঁ (Future অবজেক্ট ব্যবহার করে)। |
| মেথডের নাম | run() | call() |
| Exception Handling | চেকড এক্সেপশন সমর্থন করে না। | চেকড এক্সেপশন থ্রো করতে পারে। |
| Future Integration | Future অবজেক্ট সাপোর্ট করে না। | Future অবজেক্টের মাধ্যমে ফলাফল প্রদান করে। |
| ব্যবহার | হালকা কাজ যেখানে রিটার্ন ভ্যালু প্রয়োজন নেই। | জটিল কাজ যেখানে রিটার্ন ভ্যালু এবং এক্সেপশন হ্যান্ডলিং প্রয়োজন। |
Runnable বনাম Callable: কোনটি ব্যবহার করবেন?
- Runnable ব্যবহার করুন:
- যদি কোনো রিটার্ন ভ্যালু প্রয়োজন না হয়।
- কাজটি সহজ এবং দ্রুত সম্পন্নযোগ্য।
- আপনি
ThreadAPI বাExecutorServiceব্যবহার করছেন।
- Callable ব্যবহার করুন:
- যদি কাজের পরে একটি রিটার্ন ভ্যালু প্রয়োজন হয়।
- যদি কাজটি জটিল এবং এক্সেপশন হ্যান্ডলিং প্রয়োজন হয়।
- যদি
Futureবা অ্যাসিঙ্ক্রোনাস প্রসেসিং দরকার হয়।
উদাহরণ: Runnable বনাম Callable
import java.util.concurrent.*;
public class RunnableVsCallableExample {
public static void main(String[] args) throws Exception {
ExecutorService executor = Executors.newFixedThreadPool(2);
// Runnable উদাহরণ
Runnable myRunnable = () -> System.out.println("Runnable is running.");
executor.execute(myRunnable);
// Callable উদাহরণ
Callable<String> myCallable = () -> {
Thread.sleep(500);
return "Callable result.";
};
Future<String> future = executor.submit(myCallable);
// Callable এর রিটার্ন ভ্যালু পান
System.out.println("Callable Result: " + future.get());
executor.shutdown();
}
}
- Runnable হলো হালকা ও দ্রুত সম্পন্ন হওয়া কাজের জন্য।
- Callable ব্যবহার করুন যখন রিটার্ন ভ্যালু বা অ্যাসিঙ্ক্রোনাস প্রসেসিং প্রয়োজন।
এই পার্থক্যগুলো মনে রেখে কনকারেন্সি সম্পর্কিত কাজ আরো কার্যকরভাবে পরিচালনা করা যাবে।
Callable এবং Runnable ইন্টারফেস দুটোই জাভাতে কনকারেন্ট টাস্ক কার্যকর করার জন্য ব্যবহৃত হয়। তবে, তাদের মধ্যে কিছু গুরুত্বপূর্ণ পার্থক্য রয়েছে।
Runnable Interface
- রিটার্ন ভ্যালু নেই:
Runnableইন্টারফেস কোনো রিটার্ন ভ্যালু দেয় না।run()মেথড কেবল একটি টাস্ক সম্পন্ন করে। - চলতি থ্রেডে এক্সিকিউট হয়:
RunnableসরাসরিThreadক্লাস বাExecutorServiceদ্বারা চালানো হয়। - Exception Handling নেই:
run()মেথড চেকড এক্সেপশন থ্রো করতে পারে না। - ব্যবহার: সাধারণত হালকা কাজ সম্পাদনের জন্য ব্যবহার করা হয়।
Runnable উদাহরণ:
class MyRunnable implements Runnable {
@Override
public void run() {
System.out.println("Runnable is running: " + Thread.currentThread().getName());
}
}
public class RunnableExample {
public static void main(String[] args) {
Runnable myRunnable = new MyRunnable();
Thread thread = new Thread(myRunnable);
thread.start();
}
}
Callable Interface
- রিটার্ন ভ্যালু দেয়:
Callableইন্টারফেস একটি রিটার্ন ভ্যালু প্রদান করে। এটিcall()মেথড ব্যবহার করে। - Future অবজেক্টের মাধ্যমে রিটার্ন:
Callable-এর রিটার্ন ভ্যালুFutureঅবজেক্টের মাধ্যমে অ্যাক্সেস করা যায়। - Exception Handling সমর্থন করে:
call()মেথড চেকড এক্সেপশন থ্রো করতে পারে। - ব্যবহার: কমপ্লেক্স বা দীর্ঘমেয়াদী কাজ যেখানে রিটার্ন ভ্যালু প্রয়োজন হয়।
Callable উদাহরণ:
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
class MyCallable implements Callable<String> {
@Override
public String call() throws Exception {
Thread.sleep(1000); // কিছু কাজ করছে
return "Callable completed by: " + Thread.currentThread().getName();
}
}
public class CallableExample {
public static void main(String[] args) {
ExecutorService executor = Executors.newSingleThreadExecutor();
Callable<String> myCallable = new MyCallable();
Future<String> future = executor.submit(myCallable);
try {
System.out.println("Result: " + future.get()); // Future থেকে ফলাফল পেতে
} catch (Exception e) {
e.printStackTrace();
} finally {
executor.shutdown();
}
}
}
Callable এবং Runnable-এর মধ্যে পার্থক্য
| বৈশিষ্ট্য | Runnable | Callable |
|---|---|---|
| রিটার্ন ভ্যালু | না (void) | হ্যাঁ (Future অবজেক্ট ব্যবহার করে)। |
| মেথডের নাম | run() | call() |
| Exception Handling | চেকড এক্সেপশন সমর্থন করে না। | চেকড এক্সেপশন থ্রো করতে পারে। |
| Future Integration | Future অবজেক্ট সাপোর্ট করে না। | Future অবজেক্টের মাধ্যমে ফলাফল প্রদান করে। |
| ব্যবহার | হালকা কাজ যেখানে রিটার্ন ভ্যালু প্রয়োজন নেই। | জটিল কাজ যেখানে রিটার্ন ভ্যালু এবং এক্সেপশন হ্যান্ডলিং প্রয়োজন। |
Runnable বনাম Callable: কোনটি ব্যবহার করবেন?
- Runnable ব্যবহার করুন:
- যদি কোনো রিটার্ন ভ্যালু প্রয়োজন না হয়।
- কাজটি সহজ এবং দ্রুত সম্পন্নযোগ্য।
- আপনি
ThreadAPI বাExecutorServiceব্যবহার করছেন।
- Callable ব্যবহার করুন:
- যদি কাজের পরে একটি রিটার্ন ভ্যালু প্রয়োজন হয়।
- যদি কাজটি জটিল এবং এক্সেপশন হ্যান্ডলিং প্রয়োজন হয়।
- যদি
Futureবা অ্যাসিঙ্ক্রোনাস প্রসেসিং দরকার হয়।
উদাহরণ: Runnable বনাম Callable
import java.util.concurrent.*;
public class RunnableVsCallableExample {
public static void main(String[] args) throws Exception {
ExecutorService executor = Executors.newFixedThreadPool(2);
// Runnable উদাহরণ
Runnable myRunnable = () -> System.out.println("Runnable is running.");
executor.execute(myRunnable);
// Callable উদাহরণ
Callable<String> myCallable = () -> {
Thread.sleep(500);
return "Callable result.";
};
Future<String> future = executor.submit(myCallable);
// Callable এর রিটার্ন ভ্যালু পান
System.out.println("Callable Result: " + future.get());
executor.shutdown();
}
}
- Runnable হলো হালকা ও দ্রুত সম্পন্ন হওয়া কাজের জন্য।
- Callable ব্যবহার করুন যখন রিটার্ন ভ্যালু বা অ্যাসিঙ্ক্রোনাস প্রসেসিং প্রয়োজন।
এই পার্থক্যগুলো মনে রেখে কনকারেন্সি সম্পর্কিত কাজ আরো কার্যকরভাবে পরিচালনা করা যাবে।
Callable ইন্টারফেস জাভার java.util.concurrent প্যাকেজের একটি অংশ যা থ্রেড থেকে ফলাফল ফেরত দিতে সক্ষম। এটি Runnable ইন্টারফেসের মতো কাজ করে, তবে প্রধান পার্থক্য হলো এটি ফলাফল ফেরত দিতে পারে এবং চেকড এক্সসেপশন থ্রো করতে পারে।
Callable Interface এর বৈশিষ্ট্য
- ফলাফল ফেরত দিতে পারে:
call()মেথড ব্যবহার করে একটি মান ফেরত দেয়। - চেকড এক্সসেপশন থ্রো করতে পারে:
call()মেথড এক্সসেপশন থ্রো করতে পারে। - Future ইন্টারফেস:
Callableএর ফলাফলFutureঅবজেক্টের মাধ্যমে অ্যাক্সেস করা হয়।
Callable Interface এর মেথড
Callable ইন্টারফেসে শুধুমাত্র একটি মেথড রয়েছে:
V call() throws Exception;
Callable Interface এর ব্যবহার
১. Callable এর সাধারণ উদাহরণ
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class CallableExample {
public static void main(String[] args) {
// Executor Service তৈরি
ExecutorService executorService = Executors.newSingleThreadExecutor();
// Callable টাস্ক তৈরি
Callable<Integer> task = () -> {
System.out.println("Calculating sum...");
int sum = 0;
for (int i = 1; i <= 10; i++) {
sum += i;
}
return sum; // ফলাফল ফেরত দেয়
};
try {
// Callable টাস্ক সাবমিট করুন এবং Future রিসিভ করুন
Future<Integer> result = executorService.submit(task);
// Future থেকে ফলাফল পান
System.out.println("Result: " + result.get()); // get() মেথড ফলাফল রিটার্ন করে
} catch (Exception e) {
e.printStackTrace();
} finally {
executorService.shutdown(); // Executor বন্ধ করুন
}
}
}
২. Callable এর সাথে একাধিক টাস্ক এবং Future ব্যবহার
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class MultipleCallableExample {
public static void main(String[] args) {
// Executor Service তৈরি
ExecutorService executorService = Executors.newFixedThreadPool(3);
// Callable টাস্কের তালিকা
List<Callable<String>> tasks = new ArrayList<>();
tasks.add(() -> {
Thread.sleep(1000);
return "Task 1 completed";
});
tasks.add(() -> {
Thread.sleep(2000);
return "Task 2 completed";
});
tasks.add(() -> {
Thread.sleep(1500);
return "Task 3 completed";
});
try {
// Callable টাস্ক এক্সিকিউট করুন এবং Future লিস্ট পান
List<Future<String>> results = executorService.invokeAll(tasks);
// Future থেকে ফলাফল পান
for (Future<String> future : results) {
System.out.println(future.get()); // get() মেথডে ফলাফল রিটার্ন হয়
}
} catch (Exception e) {
e.printStackTrace();
} finally {
executorService.shutdown(); // Executor বন্ধ করুন
}
}
}
৩. Callable এর সাথে Exception Handling
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class CallableWithExceptionExample {
public static void main(String[] args) {
ExecutorService executorService = Executors.newSingleThreadExecutor();
// Callable টাস্ক তৈরি
Callable<String> task = () -> {
if (true) {
throw new RuntimeException("Something went wrong!");
}
return "Success";
};
try {
Future<String> result = executorService.submit(task);
// ফলাফল পান
System.out.println(result.get());
} catch (Exception e) {
System.out.println("Exception: " + e.getMessage());
} finally {
executorService.shutdown();
}
}
}
Callable এবং Future এর গুরুত্বপূর্ণ পয়েন্ট
submit()মেথড:- Callable টাস্ক সাবমিট করতে ব্যবহৃত হয়।
- এটি
Futureঅবজেক্ট রিটার্ন করে।
get()মেথড:Futureঅবজেক্ট থেকে ফলাফল পেতে ব্যবহৃত হয়।- এটি থ্রেডের কাজ শেষ না হলে ব্লক করে।
- Exception Handling:
- Callable ইন্টারফেস চেকড এক্সসেপশন থ্রো করতে পারে।
- Future-এর
get()মেথডExecutionExceptionথ্রো করতে পারে।
- Thread Pool ব্যবহারের সুবিধা:
- একাধিক Callable টাস্ক পরিচালনা করা সহজ হয়।
- সিস্টেমের পারফরম্যান্স উন্নত হয়।
Callable vs Runnable
| বৈশিষ্ট্য | Runnable | Callable |
|---|---|---|
| ফলাফল ফেরত | না (void) | হ্যাঁ (Generic Type) |
| Exception | চেকড এক্সসেপশন থ্রো করতে পারে না | চেকড এক্সসেপশন থ্রো করতে পারে |
| মেথড | run() | call() |
Callable Interface ব্যবহার করলে জাভা কনকারেন্সি আরও কার্যকর এবং ফলাফল ভিত্তিক হয়ে ওঠে। এটি বিশেষভাবে উপকারী যখন থ্রেড থেকে কোনো ফলাফল প্রয়োজন হয় বা ব্যতিক্রম হ্যান্ডলিং দরকার হয়।
Future এবং FutureTask কি?
Future এবং FutureTask জাভার কনকারেন্ট প্রোগ্রামিং এর অংশ, যা থ্রেড পুল বা অ্যাসিঙ্ক্রোনাস টাস্কের ফলাফল পরিচালনা করতে ব্যবহৃত হয়।
Future:
- Future ইন্টারফেস হল জাভার একটি কনকারেন্সি টুল, যা থ্রেডের মাধ্যমে অ্যাসিঙ্ক্রোনাস টাস্ক পরিচালনা করতে সাহায্য করে।
- এটি টাস্কের স্টেট চেক করা, বাতিল করা, এবং ফলাফল পেতে ব্যবহৃত হয়।
FutureTask:
- FutureTask হলো Future ইন্টারফেসের একটি ইমপ্লিমেন্টেশন।
- এটি Runnable এবং Callable উভয়কেই সমর্থন করে।
- টাস্ক চালানো এবং ফলাফল পেতে ব্যবহৃত হয়।
Future এর প্রধান মেথডসমূহ
get()
টাস্ক সম্পূর্ণ হলে ফলাফল রিটার্ন করে। এটি ব্লকিং।isDone()
চেক করে টাস্ক সম্পূর্ণ হয়েছে কিনা।cancel()
টাস্ক বাতিল করতে ব্যবহৃত হয়।isCancelled()
চেক করে টাস্ক বাতিল হয়েছে কিনা।
Future এবং ExecutorService এর উদাহরণ
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class FutureExample {
public static void main(String[] args) {
// ১. ExecutorService তৈরি
ExecutorService executor = Executors.newSingleThreadExecutor();
// ২. Callable তৈরি
Callable<Integer> task = () -> {
Thread.sleep(2000); // ২ সেকেন্ডের জন্য থ্রেড থামান
return 42; // ফলাফল রিটার্ন করুন
};
// ৩. Future এর মাধ্যমে টাস্ক সাবমিট
Future<Integer> future = executor.submit(task);
System.out.println("Task submitted, doing other work...");
try {
// ৪. Future থেকে ফলাফল পান
Integer result = future.get(); // এটি ব্লকিং
System.out.println("Task completed! Result: " + result);
} catch (Exception e) {
e.printStackTrace();
} finally {
executor.shutdown();
}
}
}
আউটপুট:
Task submitted, doing other work...
Task completed! Result: 42
FutureTask এর উদাহরণ
import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;
public class FutureTaskExample {
public static void main(String[] args) {
// ১. Callable তৈরি
Callable<String> task = () -> {
Thread.sleep(3000); // ৩ সেকেন্ড থামুন
return "Task Completed!";
};
// ২. FutureTask তৈরি
FutureTask<String> futureTask = new FutureTask<>(task);
// ৩. নতুন থ্রেডে FutureTask চালান
Thread thread = new Thread(futureTask);
thread.start();
System.out.println("Task is running...");
try {
// ৪. FutureTask থেকে ফলাফল পান
String result = futureTask.get(); // এটি ব্লকিং
System.out.println(result);
} catch (Exception e) {
e.printStackTrace();
}
}
}
আউটপুট:
Task is running...
Task Completed!
Future এবং FutureTask এর তুলনা
| বিষয় | Future | FutureTask |
|---|---|---|
| টাইপ | এটি একটি ইন্টারফেস। | এটি Future ইন্টারফেসের ইমপ্লিমেন্টেশন। |
| টাস্ক পাস করা | সরাসরি Callable বা Runnable ব্যবহার করা হয় না। | Callable বা Runnable পাস করা যায়। |
| থ্রেড কন্ট্রোল | ExecutorService দ্বারা টাস্ক চালানো হয়। | সরাসরি থ্রেড বা ExecutorService ব্যবহার করা যায়। |
| টাস্ক পুনর্ব্যবহারযোগ্যতা | শুধুমাত্র একবার ব্যবহার করা যায়। | পুনর্ব্যবহারযোগ্য নয়। |
Future এর সাথে Timeout সেট করা
get() মেথডে একটি টাইমআউট প্যারামিটার ব্যবহার করে নির্দিষ্ট সময়ের জন্য অপেক্ষা করতে পারেন।
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
public class FutureTimeoutExample {
public static void main(String[] args) {
ExecutorService executor = Executors.newSingleThreadExecutor();
Callable<String> task = () -> {
Thread.sleep(5000); // ৫ সেকেন্ডের জন্য থ্রেড থামান
return "Completed!";
};
Future<String> future = executor.submit(task);
try {
// ৩ সেকেন্ড পর্যন্ত অপেক্ষা করুন
String result = future.get(3, TimeUnit.SECONDS);
System.out.println(result);
} catch (Exception e) {
System.out.println("Task did not complete in time!");
} finally {
executor.shutdown();
}
}
}
আউটপুট:
Task did not complete in time!
একাধিক Future পরিচালনা (InvokeAll এবং InvokeAny)
InvokeAll:
সকল টাস্ক সম্পন্ন হওয়া পর্যন্ত অপেক্ষা করে।
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;
public class FutureInvokeAllExample {
public static void main(String[] args) throws InterruptedException {
ExecutorService executor = Executors.newFixedThreadPool(3);
List<Callable<Integer>> tasks = new ArrayList<>();
for (int i = 1; i <= 3; i++) {
int value = i;
tasks.add(() -> value * value); // প্রতিটি টাস্কে একটি স্কয়ার রিটার্ন
}
List<Future<Integer>> futures = executor.invokeAll(tasks);
for (Future<Integer> future : futures) {
try {
System.out.println("Result: " + future.get());
} catch (Exception e) {
e.printStackTrace();
}
}
executor.shutdown();
}
}
InvokeAny:
যে টাস্ক প্রথম সম্পন্ন হয় তার ফলাফল রিটার্ন করে।
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;
public class FutureInvokeAnyExample {
public static void main(String[] args) throws InterruptedException, ExecutionException {
ExecutorService executor = Executors.newFixedThreadPool(3);
List<Callable<Integer>> tasks = new ArrayList<>();
for (int i = 1; i <= 3; i++) {
int value = i;
tasks.add(() -> {
Thread.sleep(value * 1000); // সময় নির্ভর টাস্ক
return value;
});
}
int result = executor.invokeAny(tasks);
System.out.println("First completed result: " + result);
executor.shutdown();
}
}
- Future এবং FutureTask অ্যাসিঙ্ক্রোনাস প্রোগ্রামিংকে সহজ করে তোলে।
- Future: টাস্কের ফলাফল বা অবস্থা জানতে ব্যবহার করা হয়।
- FutureTask: Callable বা Runnable এর সাথে ফলাফল পরিচালনার জন্য একটি শক্তিশালী টুল।
ব্যবহার করার সময় প্রকল্পের প্রয়োজন এবং জটিলতা অনুযায়ী Future বা FutureTask বেছে নিন।
১. Timeout Handling
Timeout Handling এর মাধ্যমে একটি অপারেশন নির্দিষ্ট সময়ের মধ্যে সম্পন্ন করা হয় কি না তা নিশ্চিত করা হয়। এটি মাল্টি-থ্রেডেড অ্যাপ্লিকেশনগুলোতে অপরিহার্য, যেখানে লম্বা সময়ের জন্য একটি থ্রেড আটকে থাকলে অ্যাপ্লিকেশনের কর্মক্ষমতা প্রভাবিত হতে পারে।
কৌশলসমূহ
- ExecutorService এর
invokeAll()বাinvokeAny()ব্যবহার। - Future API এর
get(timeout, unit)মেথড ব্যবহার। - ReentrantLock এর
tryLock()ব্যবহার।
Timeout Handling উদাহরণ
১. Future API এবং Timeout
import java.util.concurrent.*;
public class TimeoutExample {
public static void main(String[] args) {
ExecutorService executor = Executors.newSingleThreadExecutor();
Callable<String> task = () -> {
Thread.sleep(3000); // Simulating long-running task
return "Task Completed";
};
Future<String> future = executor.submit(task);
try {
String result = future.get(2, TimeUnit.SECONDS); // Timeout after 2 seconds
System.out.println(result);
} catch (TimeoutException e) {
System.out.println("Task timed out");
future.cancel(true); // Cancel the task
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
} finally {
executor.shutdown();
}
}
}
২. ReentrantLock এবং tryLock()
import java.util.concurrent.locks.ReentrantLock;
public class LockTimeoutExample {
public static void main(String[] args) {
ReentrantLock lock = new ReentrantLock();
Thread thread = new Thread(() -> {
try {
if (lock.tryLock(2, TimeUnit.SECONDS)) { // Try acquiring lock for 2 seconds
try {
System.out.println("Lock acquired");
Thread.sleep(3000); // Simulating work
} finally {
lock.unlock();
}
} else {
System.out.println("Could not acquire lock within timeout");
}
} catch (InterruptedException e) {
e.printStackTrace();
}
});
thread.start();
}
}
২. Asynchronous Computation
Asynchronous Computation এর মাধ্যমে একটি কাজ ব্যাকগ্রাউন্ডে সম্পন্ন করা হয় এবং এর ফলাফল প্রস্তুত হলে কেবল তখন থ্রেডের সাথে যোগাযোগ করা হয়। এটি CPU ব্যবহার বাড়ায় এবং UI-কে রেসপন্সিভ রাখে।
কৌশলসমূহ
- CompletableFuture API
- ExecutorService ব্যবহার করে
submit()বাinvokeAll()। - ForkJoinPool ব্যবহার।
Asynchronous Computation উদাহরণ
১. CompletableFuture উদাহরণ
import java.util.concurrent.CompletableFuture;
public class AsyncComputationExample {
public static void main(String[] args) {
CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
try {
Thread.sleep(2000); // Simulating long task
System.out.println("Task completed asynchronously");
} catch (InterruptedException e) {
e.printStackTrace();
}
});
System.out.println("Main thread continues...");
// Waiting for the asynchronous task to complete
future.join();
}
}
২. CompletableFuture এর সাথে চেইনিং
import java.util.concurrent.CompletableFuture;
public class CompletableFutureChaining {
public static void main(String[] args) {
CompletableFuture.supplyAsync(() -> {
return "Step 1 Result";
}).thenApply(result -> {
System.out.println(result);
return "Step 2 Result";
}).thenAccept(result -> {
System.out.println(result);
}).exceptionally(ex -> {
System.out.println("Exception: " + ex.getMessage());
return null;
});
}
}
৩. ExecutorService এর সাথে Asynchronous Computation
import java.util.concurrent.*;
public class ExecutorServiceExample {
public static void main(String[] args) throws InterruptedException {
ExecutorService executor = Executors.newCachedThreadPool();
Callable<Integer> task1 = () -> {
Thread.sleep(1000);
return 10;
};
Callable<Integer> task2 = () -> {
Thread.sleep(2000);
return 20;
};
Future<Integer> future1 = executor.submit(task1);
Future<Integer> future2 = executor.submit(task2);
System.out.println("Tasks submitted. Main thread continues...");
try {
int result1 = future1.get();
int result2 = future2.get();
System.out.println("Result: " + (result1 + result2));
} catch (ExecutionException e) {
e.printStackTrace();
} finally {
executor.shutdown();
}
}
}
৩. Timeout এবং Asynchronous Computation একসঙ্গে
import java.util.concurrent.*;
public class AsyncTimeoutExample {
public static void main(String[] args) {
ExecutorService executor = Executors.newSingleThreadExecutor();
Callable<String> task = () -> {
Thread.sleep(4000); // Simulate a long task
return "Task Completed";
};
Future<String> future = executor.submit(task);
CompletableFuture.runAsync(() -> {
try {
System.out.println("Result: " + future.get(2, TimeUnit.SECONDS)); // Timeout of 2 seconds
} catch (TimeoutException e) {
System.out.println("Task timed out");
future.cancel(true); // Cancel the task
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}).join();
executor.shutdown();
}
}
Timeout এবং Asynchronous Computation এর সুবিধা
- উচ্চ কার্যকারিতা:
ব্যাকগ্রাউন্ড প্রসেস এবং টাইমআউট হ্যান্ডলিং ব্যবহার করে অ্যাপ্লিকেশন দ্রুত এবং সঠিকভাবে কাজ করে। - রিসোর্স ব্যবস্থাপনা:
নির্দিষ্ট সময়ে অপারেশন শেষ না হলে, তা বাতিল করে রিসোর্স সংরক্ষণ করা যায়। - ইউজার অভিজ্ঞতা উন্নত করা:
UI ব্লক না করে ব্যাকগ্রাউন্ডে কাজ করতে পারে। - স্কেলেবিলিটি:
অ্যাসিঙ্ক্রোনাস মডেল ব্যবহারে অ্যাপ্লিকেশন আরও স্কেলেবল হয়।
- Timeout Handling দীর্ঘ চলমান কাজগুলোর সময় সীমাবদ্ধ করে অ্যাপ্লিকেশনকে কার্যকর রাখতে সাহায্য করে।
- Asynchronous Computation ব্যাকগ্রাউন্ড প্রসেস পরিচালনা করে CPU ব্যবহার বৃদ্ধি করে এবং মাল্টি-থ্রেডেড অ্যাপ্লিকেশন সহজ করে।
CompletableFuture API এবং Future API ব্যবহার করে সহজেই টাইমআউট এবং অ্যাসিঙ্ক্রোনাস প্রক্রিয়া বাস্তবায়ন করা যায়।
Read more