Guava লাইব্রেরি Concurrency Utilities সরবরাহ করে, যা Java অ্যাপ্লিকেশনগুলির মধ্যে বহুমুখী কার্যক্রম পরিচালনা এবং থ্রেড ব্যবস্থাপনা সহজ করে তোলে। Guava-এর concurrent প্যাকেজটি অ্যাসিঙ্ক্রোনাস প্রোগ্রামিং, থ্রেডপুল ব্যবস্থাপনা, এবং বহুবিধ থ্রেডের জন্য কার্যকরী সমাধান প্রদান করে। এতে বিভিন্ন ইউটিলিটি ক্লাস ও মেথড রয়েছে যা মুলত Java Concurrency API-এর উন্নত সংস্করণ হিসেবে কাজ করে।
Guava Concurrency Utilities-এর প্রধান উপাদান
Guava লাইব্রেরির concurrency utilities মূলত কয়েকটি গুরুত্বপূর্ণ ফিচার সরবরাহ করে, যেমন ListenableFuture, ListeningExecutorService, এবং ListeningExecutorService যা Java concurrency-র কাজগুলিকে আরও সহজ ও কার্যকরী করে তোলে।
1. ListenableFuture
ListenableFuture হল একটি উন্নত Future ক্লাস যা শুধুমাত্র Future.get() মেথড ব্যবহার করার চেয়ে আরো বেশি সুবিধা প্রদান করে। এটি অ্যাসিঙ্ক্রোনাস কাজের জন্য একটি সহজ API প্রদান করে এবং আরও সহজে callback হ্যান্ডলিং করতে পারে।
ListenableFutureব্যবহারকারীকে কোন কাজ শেষ হওয়ার পর অবিলম্বে কলব্যাক ফাংশন (callback function) পরিচালনার সুবিধা দেয়। এটিaddListener()মেথডের মাধ্যমে সম্ভব।
উদাহরণ:
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.ListeningExecutorService;
import com.google.common.util.concurrent.MoreExecutors;
import com.google.common.util.concurrent.SettableFuture;
import java.util.concurrent.Callable;
import java.util.concurrent.Executors;
public class ListenableFutureExample {
public static void main(String[] args) throws Exception {
ListeningExecutorService service = MoreExecutors.listeningDecorator(Executors.newCachedThreadPool());
// একটি টাস্ক তৈরি
ListenableFuture<String> future = service.submit(new Callable<String>() {
@Override
public String call() throws Exception {
Thread.sleep(2000); // কিছু সময় নেওয়া হচ্ছে
return "Task Completed";
}
});
// কলব্যাক সেট করা
future.addListener(() -> {
try {
System.out.println(future.get()); // "Task Completed"
} catch (Exception e) {
e.printStackTrace();
}
}, service);
}
}
এখানে, যখন কাজটি শেষ হয়, তখন addListener() মেথডের মাধ্যমে Task Completed প্রিন্ট করা হবে। এটি অ্যাসিঙ্ক্রোনাসভাবে কাজ সম্পন্ন হওয়ার পর কলব্যাক হ্যান্ডলিং করতে সাহায্য করে।
2. ListeningExecutorService
ListeningExecutorService হল একটি উন্নত ExecutorService যা ListenableFuture এর সাথে কাজ করে এবং এটি অ্যাসিঙ্ক্রোনাস টাস্ক এক্সিকিউশন সহজ করে তোলে। ListeningExecutorService এর মাধ্যমে কাজের সমন্বয় এবং কলব্যাকগুলি পরিচালনা করা সহজ হয়।
উদাহরণ:
import com.google.common.util.concurrent.ListeningExecutorService;
import com.google.common.util.concurrent.MoreExecutors;
import com.google.common.util.concurrent.ListenableFuture;
import java.util.concurrent.Callable;
import java.util.concurrent.Executors;
public class ListeningExecutorServiceExample {
public static void main(String[] args) throws Exception {
ListeningExecutorService executorService = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(2));
ListenableFuture<Integer> future1 = executorService.submit(new Callable<Integer>() {
@Override
public Integer call() {
return 10 + 20; // একটি গাণিতিক কাজ
}
});
ListenableFuture<Integer> future2 = executorService.submit(new Callable<Integer>() {
@Override
public Integer call() {
return 30 + 40; // একটি গাণিতিক কাজ
}
});
// দুটি Future-এর ফলাফল একত্রিত করা
System.out.println("Result 1: " + future1.get());
System.out.println("Result 2: " + future2.get());
}
}
এখানে, দুটি আলাদা গাণিতিক কাজ চলতে থাকবে এবং প্রতিটি ListenableFuture তার কাজ শেষ হলে ফলাফল প্রদান করবে। এটি অ্যাসিঙ্ক্রোনাস কাজের জন্য বেশ সুবিধাজনক।
3. ListeningExecutorService এবং Futures
Guava লাইব্রেরি Futures ক্লাসের মাধ্যমে অনেক কার্যকরী মেথড সরবরাহ করে, যেমন Futures.successfulAsList() বা Futures.transform() যা অ্যাসিঙ্ক্রোনাস কাজের ফলাফল একত্রিত করতে সাহায্য করে।
উদাহরণ:
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.ListeningExecutorService;
import com.google.common.util.concurrent.MoreExecutors;
import com.google.common.util.concurrent.Futures;
import java.util.concurrent.Callable;
import java.util.concurrent.Executors;
import java.util.List;
public class FuturesExample {
public static void main(String[] args) throws Exception {
ListeningExecutorService executorService = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(2));
// দুটি ফিউচার টাস্ক
ListenableFuture<Integer> future1 = executorService.submit(() -> 10 + 10);
ListenableFuture<Integer> future2 = executorService.submit(() -> 20 + 20);
// Futures.successfulAsList() ব্যবহার করে দুটি ফিউচার একত্রিত করা
ListenableFuture<List<Integer>> allFutures = Futures.successfulAsList(future1, future2);
// সমস্ত ফলাফল একত্রিত করা
List<Integer> results = allFutures.get();
System.out.println("Results: " + results); // [20, 40]
}
}
এখানে, Futures.successfulAsList() মেথড ব্যবহার করে দুটি ফিউচার একত্রিত করা হয়েছে এবং শেষে তাদের ফলাফল পাওয়া গেছে।
4. Catching and Transforming Futures
Guava ফিউচারের সাথে আরও উন্নত অপারেশন করতে দেয়, যেমন catching exceptions এবং transforming results। Futures.transform() মেথড ব্যবহার করে আপনি ফিউচারের ফলাফল পরিবর্তন করতে পারেন বা এক্সেপশন হ্যান্ডলিং করতে পারেন।
উদাহরণ:
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.ListeningExecutorService;
import com.google.common.util.concurrent.MoreExecutors;
import java.util.concurrent.Callable;
import java.util.concurrent.Executors;
public class TransformingFutureExample {
public static void main(String[] args) throws Exception {
ListeningExecutorService executorService = MoreExecutors.listeningDecorator(Executors.newCachedThreadPool());
ListenableFuture<Integer> future = executorService.submit(new Callable<Integer>() {
@Override
public Integer call() throws Exception {
return 10 / 0; // ডিভাইড বাই জিরো এক্সেপশন
}
});
ListenableFuture<Integer> transformedFuture = Futures.catching(future, ArithmeticException.class, e -> 0);
System.out.println("Transformed Result: " + transformedFuture.get()); // 0
}
}
এখানে, যদি কোনও এক্সেপশন ঘটে (যেমন ArithmeticException), তবে catching() মেথড ব্যবহার করে সেই এক্সেপশনকে হ্যান্ডেল করা হয়েছে এবং ০ রিটার্ন করা হয়েছে।
Guava Concurrency Utilities এর সুবিধা
- সহজ অ্যাসিঙ্ক্রোনাস অপারেশন:
ListenableFutureএবংListeningExecutorServiceব্যবহার করে অ্যাসিঙ্ক্রোনাস প্রোগ্রামিং সহজ এবং আরও কার্যকরী করা যায়। - কলব্যাক হ্যান্ডলিং:
ListenableFuture.addListener()মেথড দ্বারা কলব্যাক সহজভাবে ব্যবস্থাপনা করা যায়, যা ফিউচার ফলাফল পাওয়ার পর নির্দিষ্ট কাজ করা সম্ভব। - কমপ্লেক্স কনকারেন্ট অপারেশন ম্যানেজমেন্ট:
Futuresক্লাস বিভিন্ন ফিউচার এবং তাদের ফলাফলগুলির সাথে কাজ করার জন্য শক্তিশালী মেথড সরবরাহ করে। - এস্ট্র্যাক্ট এক্সেপশন হ্যান্ডলিং: Guava এর
Futures.catching()মেথড দ্বারা ফিউচার এর মধ্যে ঘটিত এক্সেপশন সহজভাবে হ্যান্ডল করা যায়।
Guava এর Concurrency Utilities জাভা অ্যাপ্লিকেশনে অ্যাসিঙ্ক্রোনাস কাজ এবং বহুবিধ থ্রেড ব্যবস্থাপনা সহজ করে তোলে, যা উন্নত পারফরম্যান্স এবং স্কেলেবিলিটি নিশ্চিত করতে সাহায্য করে।
Guava লাইব্রেরি Java অ্যাপ্লিকেশনগুলিতে কনকারেন্ট (concurrent) প্রোগ্রামিং সহজ করার জন্য শক্তিশালী ইউটিলিটি সরবরাহ করে। এর মধ্যে দুটি গুরুত্বপূর্ণ ধারণা হল ListenableFuture এবং Futures, যা অ্যাসিনক্রোনাস অপারেশনগুলি পরিচালনা এবং তাদের ফলাফল প্রাপ্তি সহজ করে তোলে। এই দুটি ফিচার Java অ্যাপ্লিকেশনে কনকারেন্সি এবং প্যারালাল প্রোগ্রামিংয়ের জন্য অত্যন্ত উপকারী।
ListenableFuture এর ধারণা
ListenableFuture হল একটি ইন্টারফেস যা Guava এর Future ক্লাসের উপর ভিত্তি করে কাজ করে, তবে এটি আরও শক্তিশালী, কারণ এটি কলব্যাক (callback) এবং ফলাফল প্রাপ্তির জন্য addListener() মেথড সরবরাহ করে। Future ক্লাস সাধারণত অ্যাসিনক্রোনাস অপারেশনগুলির ফলাফল (যেমন, থ্রেডের মাধ্যমে চলা দীর্ঘ সময়ের অপারেশন) সংগ্রহ করতে ব্যবহৃত হয়, তবে ListenableFuture এর মাধ্যমে আপনি সহজেই ফলাফল পাওয়ার পর একটি নির্দিষ্ট কার্যকলাপ (callback) পরিচালনা করতে পারেন।
ListenableFuture এর বৈশিষ্ট্য:
- এটি অ্যাসিনক্রোনাস অপারেশন সম্পন্ন হলে আপনি একটি কলব্যাক যুক্ত করতে পারেন।
ListenableFutureএর সাথে কাজ করতে পারলে আপনি ব্লকিং অপারেশন না করে ফলাফল পেতে পারেন।- আপনি যখন
addListener()মেথড ব্যবহার করেন, তখন এটি নির্দিষ্ট থ্রেডে (যেমন, GUI থ্রেড বা বিশেষ কোনো থ্রেডে) কলব্যাক কার্যকর করবে।
উদাহরণ:
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.ListeningExecutorService;
import com.google.common.util.concurrent.MoreExecutors;
import com.google.common.util.concurrent.ListenableFuture;
import java.util.concurrent.Executors;
import java.util.concurrent.Callable;
public class ListenableFutureExample {
public static void main(String[] args) throws Exception {
// ExecutorService তৈরি
ListeningExecutorService service = MoreExecutors.listeningDecorator(Executors.newCachedThreadPool());
// অ্যাসিনক্রোনাস কাজ
ListenableFuture<String> future = service.submit(new Callable<String>() {
@Override
public String call() throws Exception {
// কিছু সময় নেওয়া কাজ
Thread.sleep(2000);
return "Task Completed!";
}
});
// ফলাফল পাওয়ার পর কলব্যাক অ্যাড করা
future.addListener(() -> {
try {
System.out.println("Task Result: " + future.get());
} catch (Exception e) {
e.printStackTrace();
}
}, service);
// থ্রেড বন্ধ করা
service.shutdown();
}
}
এই উদাহরণে, ListenableFuture ব্যবহৃত হয়েছে, যা addListener() মেথডের মাধ্যমে একটি কলব্যাক যুক্ত করা হয়েছে। কাজটি শেষ হওয়ার পর কলব্যাক অ্যাক্টিভেট হবে এবং তার ফলাফল প্রদর্শন করবে।
Futures এর ধারণা
Guava এর Futures ক্লাস হল বিভিন্ন ফাংশনালিটির একটি সেট যা Future এবং ListenableFuture এর সাথে কাজ করার জন্য ব্যবহৃত হয়। এটি ListenableFuture এবং Future এর উপর বিভিন্ন ইউটিলিটি প্রদান করে, যেমন:
Futures.addCallback()- কলব্যাক অ্যাড করাFutures.transform()- আসিনক্রোনাস ফলাফলকে ট্রান্সফর্ম করাFutures.allAsList()- একাধিকFutureএর সব ফলাফল একত্র করা
Futures ক্লাসের সাহায্যে আপনি একাধিক অ্যাসিনক্রোনাস কাজের ফলাফলকে সহজভাবে একত্রিত এবং পরিচালনা করতে পারেন।
Futures এর কিছু গুরুত্বপূর্ণ মেথড:
- Futures.addCallback()
- এটি
ListenableFutureএর জন্য একটি সহজ পদ্ধতি প্রদান করে, যার মাধ্যমে আপনি সফল এবং ব্যর্থ উভয় পরিস্থিতিতে কলব্যাক অ্যাড করতে পারেন।
- এটি
- Futures.transform()
- এটি
ListenableFutureবাFutureএর ফলাফলকে কোনো অন্য ধরনের ফলাফলে রূপান্তর করতে ব্যবহৃত হয়। উদাহরণস্বরূপ, আপনি যদি একটি অ্যাসিনক্রোনাস কাজের পরে কিছু হিসাব করতে চান, তবে এটি খুব উপকারী।
- এটি
- Futures.allAsList()
- এটি একাধিক
Futureকে একটিListenableFutureএ একত্রিত করে, যা সব কাজ সম্পন্ন হলে একটি পূর্ণাঙ্গ ফলাফল প্রদান করে।
- এটি একাধিক
উদাহরণ:
import com.google.common.util.concurrent.*;
import java.util.concurrent.*;
public class FuturesExample {
public static void main(String[] args) throws Exception {
ListeningExecutorService service = MoreExecutors.listeningDecorator(Executors.newCachedThreadPool());
ListenableFuture<Integer> future1 = service.submit(() -> 10);
ListenableFuture<Integer> future2 = service.submit(() -> 20);
// Futures.allAsList() ব্যবহার করা হয়েছে যাতে সব ফিউচার একত্রিত হয়ে একটি ফলাফল প্রদান করে
ListenableFuture<List<Integer>> allFutures = Futures.allAsList(future1, future2);
// Futures.addCallback() ব্যবহার করে সাফল্য এবং ব্যর্থতার ক্ষেত্রে কলব্যাক যোগ করা
Futures.addCallback(allFutures, new FutureCallback<List<Integer>>() {
@Override
public void onSuccess(List<Integer> result) {
System.out.println("All Futures Completed: " + result);
}
@Override
public void onFailure(Throwable t) {
t.printStackTrace();
}
}, service);
service.shutdown();
}
}
এখানে, Futures.allAsList() ব্যবহার করে আমরা দুটি ListenableFuture এর ফলাফল একত্রিত করেছি এবং Futures.addCallback() ব্যবহার করে তাদের সফল ফলাফলের উপর একটি কলব্যাক অ্যাড করেছি।
সারাংশ
Guava এর ListenableFuture এবং Futures ক্লাস Java অ্যাপ্লিকেশনে অ্যাসিনক্রোনাস প্রোগ্রামিংকে আরো শক্তিশালী এবং সহজ করে তোলে। ListenableFuture আপনাকে অ্যাসিনক্রোনাস কাজগুলোর সাথে ইন্টারঅ্যাক্ট করার জন্য কলব্যাক এবং ফলাফল সংগ্রহের জন্য আরও বেশি নমনীয়তা প্রদান করে, এবং Futures ক্লাস আপনাকে একাধিক অ্যাসিনক্রোনাস অপারেশনের ফলাফল একত্রিত করতে, ফলাফল ট্রান্সফর্ম করতে, এবং কলব্যাক ব্যবস্থাপনা সহজ করতে সহায়তা করে। এগুলি অ্যাসিনক্রোনাস কাজের পারফরম্যান্স এবং ব্যবস্থাপনায় উল্লেখযোগ্য উন্নতি সাধন করে।
Guava লাইব্রেরি জাভাতে অ্যাসিঙ্ক্রোনাস (Asynchronous) কার্যকলাপ এবং ক্যালব্যাক (Callback) হ্যান্ডলিং এর জন্য শক্তিশালী ইউটিলিটি সরবরাহ করে। Guava-এর ListenableFuture এবং ListeningExecutorService ক্লাসগুলো ব্যবহার করে আপনি সহজে অ্যাসিঙ্ক্রোনাস এক্সিকিউশন এবং ক্যালব্যাক হ্যান্ডলিং পরিচালনা করতে পারবেন। এই প্রক্রিয়াগুলি আপনার অ্যাপ্লিকেশনে নিরবচ্ছিন্নভাবে কার্যক্রম চালিয়ে যেতে সহায়তা করে, যাতে UI থ্রেড ব্লক না হয় এবং অন্যান্য কার্যক্রম চালানো যায়।
Async Execution এর ধারণা
Asynchronous Execution হল এমন একটি পদ্ধতি যেখানে কার্যকলাপ (tasks) একসাথে সিঙ্ক্রোনাসভাবে না চলে় আলাদা আলাদা থ্রেডে সম্পন্ন হয়। এর ফলে এক বা একাধিক দীর্ঘ-running কাজ সম্পাদন করার সময় অন্য কাজের ক্ষেত্রে বিলম্ব (delay) ঘটে না। Java-তে অ্যাসিঙ্ক্রোনাস কার্যকলাপ ব্যবহারের জন্য Guava লাইব্রেরির ListenableFuture এবং ListeningExecutorService ব্যবহার করা হয়।
ListenableFuture এবং ListeningExecutorService
ListenableFuture: এটি Guava-এর একটি ইন্টারফেস যা java.util.concurrent.Future এর মতো কাজ করে, কিন্তু এর সাথে ক্যালব্যাক হ্যান্ডলিং (callback handling) সহজ করা হয়। এর মাধ্যমে আপনি নির্দিষ্ট কাজ সম্পন্ন হওয়ার পরে (success or failure) একটি ক্যালব্যাক কার্যকরী করতে পারেন।
ListeningExecutorService: এটি Guava-এর একটি ইন্টারফেস যা java.util.concurrent.ExecutorService এর মতো, কিন্তু এটি ListenableFuture রিটার্ন করে এবং ক্যালব্যাকগুলোর ব্যবস্থাপনা সহজ করে।
Async Execution এর জন্য উদাহরণ
ধরা যাক, আপনি এমন একটি অ্যাসিঙ্ক্রোনাস কাজ করতে চান, যেখানে একটি দীর্ঘ-running প্রসেস (যেমন ফাইল ডাউনলোড বা ডেটাবেস থেকে ডেটা ফেচ) সম্পন্ন হলে আপনি ফলাফল নিতে পারবেন এবং পরে সেটির ওপর নির্দিষ্ট কাজ করতে পারবেন।
উদাহরণ: ListenableFuture ব্যবহার করে অ্যাসিঙ্ক্রোনাস কাজ
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.ListeningExecutorService;
import com.google.common.util.concurrent.MoreExecutors;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import java.util.concurrent.Callable;
import java.util.concurrent.Executors;
public class AsyncExecutionExample {
public static void main(String[] args) throws Exception {
// ExecutorService তৈরি করা
ListeningExecutorService service = MoreExecutors.listeningDecorator(
Executors.newFixedThreadPool(2, new ThreadFactoryBuilder().setNameFormat("worker-thread-%d").build())
);
// অ্যাসিঙ্ক্রোনাস কাজের জন্য Callable ব্যবহার
Callable<String> task = () -> {
Thread.sleep(2000); // 2 সেকেন্ড অপেক্ষা করা
return "Task completed!";
};
// ListenableFuture তৈরি করা
ListenableFuture<String> future = service.submit(task);
// যখন কাজটি শেষ হবে, তখন ক্যালব্যাকে ফলাফল পাবে
future.addListener(() -> {
try {
// ক্যালব্যাক: কাজের ফলাফল প্রিন্ট করা
System.out.println(future.get());
} catch (Exception e) {
e.printStackTrace();
}
}, service);
// Main thread অন্য কাজ চালাতে পারে
System.out.println("Main thread is free to do other work.");
}
}
এখানে, ListenableFuture দ্বারা অ্যাসিঙ্ক্রোনাস কাজ সম্পন্ন হওয়ার পর ক্যালব্যাক কার্যকরী হয় এবং ফলাফল মুদ্রিত হয়। addListener() মেথডটি ক্যালব্যাক পরিচালনা করে, যাতে কাজের সম্পন্ন হওয়ার পরে আপনি নির্দিষ্ট কার্যক্রম সম্পাদন করতে পারেন।
Callback Handling
Callback Handling হল এমন একটি প্রক্রিয়া, যেখানে একটি প্রোগ্রাম বা সিস্টেম অন্য একটি কার্যক্রমের শেষে ফলাফল পাওয়ার জন্য অপেক্ষা করে এবং তারপরে সেই ফলাফল ব্যবহার করে পরবর্তী কার্যক্রমটি চালায়। Guava-তে ListenableFuture এবং addListener() এর মাধ্যমে ক্যালব্যাক হ্যান্ডলিং সহজ করা হয়েছে।
Callback Handling এর জন্য উদাহরণ
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.ListeningExecutorService;
import com.google.common.util.concurrent.MoreExecutors;
import com.google.common.util.concurrent.Futures;
import java.util.concurrent.Callable;
import java.util.concurrent.Executors;
public class CallbackHandlingExample {
public static void main(String[] args) throws Exception {
// ExecutorService তৈরি করা
ListeningExecutorService service = MoreExecutors.listeningDecorator(
Executors.newFixedThreadPool(2)
);
// একটি সহজ Callable কাজ যা 3 সেকেন্ডে ফলাফল দেয়
Callable<String> task = () -> {
Thread.sleep(3000); // 3 সেকেন্ড অপেক্ষা করা
return "Task Finished!";
};
// ListenableFuture তৈরি করা
ListenableFuture<String> future = service.submit(task);
// কাজ শেষ হওয়ার পর একটি ক্যালব্যাক পরিচালনা করা
Futures.addCallback(future, new com.google.common.util.concurrent.FutureCallback<String>() {
@Override
public void onSuccess(String result) {
// সফল হলে কাজের ফলাফল প্রিন্ট করা
System.out.println("Callback received: " + result);
}
@Override
public void onFailure(Throwable t) {
// কোনো ত্রুটি হলে ত্রুটি বার্তা প্রিন্ট করা
t.printStackTrace();
}
}, service);
// Main thread অন্যান্য কাজ চালাতে পারে
System.out.println("Main thread is free while task is running.");
}
}
এখানে, Futures.addCallback() মেথড ব্যবহার করে অ্যাসিঙ্ক্রোনাস কাজের সফল বা ব্যর্থ ফলাফল পাওয়া গেলে ক্যালব্যাক হ্যান্ডলিং করা হয়েছে। ক্যালব্যাকের মাধ্যমে সফল ফলাফল বা ত্রুটি বার্তা প্রসেস করা হচ্ছে।
Advantages of Async Execution and Callback Handling
- Non-blocking operations: অ্যাসিঙ্ক্রোনাস এক্সিকিউশন থ্রেডের ব্লকিং এড়াতে সহায়তা করে, তাই ইউআই বা প্রধান থ্রেড অবিচ্ছিন্নভাবে কাজ চালিয়ে যেতে পারে।
- Improved performance: একাধিক কাজ একসাথে পরিচালনা করা সম্ভব, যেমন নেটওয়ার্ক কল বা ডাটাবেস এক্সিকিউশন, যা থ্রেডের কার্যকারিতা উন্নত করে।
- Easy callback management: Guava এর
ListenableFutureএবংFutures.addCallback()মেথড সহজে ক্যালব্যাক হ্যান্ডলিং বাস্তবায়ন করতে সহায়তা করে।
সারাংশ
Guava লাইব্রেরি Async Execution এবং Callback Handling এর জন্য শক্তিশালী এবং সহজ টুল সরবরাহ করে। ListenableFuture এবং ListeningExecutorService এর মাধ্যমে অ্যাসিঙ্ক্রোনাস কাজগুলির কার্যকরী বাস্তবায়ন এবং ফলাফল পাওয়ার পরে ক্যালব্যাক হ্যান্ডলিং করা সম্ভব। এই ফিচারগুলির মাধ্যমে আপনি আপনার অ্যাপ্লিকেশনের পারফরম্যান্স উন্নত করতে পারেন এবং আরও মসৃণ এবং দ্রুত কার্যকারিতা নিশ্চিত করতে পারবেন।
Guava লাইব্রেরি Futures ক্লাসের মাধ্যমে ফিউচার এবং অ্যাসিঙ্ক্রোনাস প্রোগ্রামিং এর কাজ সহজ করে তোলে। Futures.transform() এবং Futures.addCallback() দুটি গুরুত্বপূর্ণ মেথড যা আসিঙ্ক্রোনাস অপারেশনগুলির সাথে কাজ করার জন্য ব্যবহৃত হয়। এগুলি বিশেষ করে ডেটা প্রসেসিং এবং অ্যাসিঙ্ক্রোনাস অপারেশনগুলিতে ফলাফল প্রাপ্তি এবং প্রতিক্রিয়া ব্যবস্থাপনা সহজ করে।
Futures.transform() এর ধারণা
Futures.transform() একটি মেথড যা একটি ফিউচার (Future) এর ফলাফলকে প্রসেস করার জন্য ব্যবহার করা হয়। এটি একটি ফাংশন গ্রহণ করে, যা ফিউচার এর ফলাফল পাওয়ার পর প্রয়োগ করা হয় এবং একটি নতুন ফিউচার রিটার্ন করে।
এই মেথডটি সাধারণত সেই ক্ষেত্রে ব্যবহার করা হয় যখন আপনি একটি ফিউচারের ফলাফল নিয়ে কিছু কার্যকরী কাজ করতে চান এবং সেই কাজটি সম্পন্ন হওয়ার পর নতুন একটি ফিউচার তৈরির প্রয়োজন হয়।
Futures.transform() ব্যবহার
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListeningExecutorService;
import com.google.common.util.concurrent.MoreExecutors;
import java.util.concurrent.Callable;
import java.util.concurrent.Executors;
public class FuturesTransformExample {
public static void main(String[] args) throws Exception {
ListeningExecutorService executorService = MoreExecutors.listeningDecorator(Executors.newCachedThreadPool());
// একটি ফিউচার তৈরি করা
ListenableFuture<Integer> future = executorService.submit(new Callable<Integer>() {
@Override
public Integer call() throws Exception {
return 10;
}
});
// Futures.transform() ব্যবহার করে ফিউচারের মান পরিবর্তন করা
ListenableFuture<String> transformedFuture = Futures.transform(future, result -> "Transformed result: " + (result * 2));
// ফলাফল প্রাপ্তি
System.out.println("Transformed Result: " + transformedFuture.get());
executorService.shutdown();
}
}
আউটপুট:
Transformed Result: Transformed result: 20
উপরের কোডে, প্রথমে একটি ফিউচার তৈরি করা হয়েছে যা একটি সংখ্যা ১০ রিটার্ন করবে। তারপর Futures.transform() ব্যবহার করে আমরা সেই সংখ্যাটির সাথে গুণফল (multiplication) করে নতুন একটি ফিউচার তৈরি করেছি।
Futures.addCallback() এর ধারণা
Futures.addCallback() মেথডটি একটি ফিউচার কমপ্লিশন রেকগনাইজার হিসেবে কাজ করে, যেখানে ফিউচারটির কাজ শেষ হওয়ার পর একাধিক কলব্যাক ফাংশন চালু করা হয়। এটি দুটি পারামিটার নেয়: একটিই SuccessCallback, যা সফল হলে চলে, এবং একটিই FailureCallback, যা কোনো ত্রুটি ঘটলে চলে। এটি ListenableFuture এর জন্য ব্যবহৃত হয়।
এই মেথডটি ব্যবহৃত হয় যখন আপনি ফিউচারের কাজ সফল হলে একটি নির্দিষ্ট কাজ করতে চান এবং যদি কোনো ত্রুটি ঘটে তাহলে তার প্রতিক্রিয়া করতে চান।
Futures.addCallback() ব্যবহার
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListeningExecutorService;
import com.google.common.util.concurrent.MoreExecutors;
import com.google.common.util.concurrent.FutureCallback;
import java.util.concurrent.Callable;
import java.util.concurrent.Executors;
public class FuturesAddCallbackExample {
public static void main(String[] args) {
ListeningExecutorService executorService = MoreExecutors.listeningDecorator(Executors.newCachedThreadPool());
// একটি ফিউচার তৈরি করা
ListenableFuture<Integer> future = executorService.submit(new Callable<Integer>() {
@Override
public Integer call() throws Exception {
// একটি নম্বর রিটার্ন করা
return 42;
}
});
// Futures.addCallback() ব্যবহার করে সফল এবং ত্রুটির ক্ষেত্রে কলব্যাক করা
Futures.addCallback(future, new FutureCallback<Integer>() {
@Override
public void onSuccess(Integer result) {
System.out.println("Success! Result: " + result);
}
@Override
public void onFailure(Throwable t) {
System.err.println("Failure: " + t.getMessage());
}
}, executorService);
executorService.shutdown();
}
}
আউটপুট:
Success! Result: 42
উপরের কোডে, একটি ফিউচার তৈরি করা হয়েছে যা একটি ইন্টিজার মান 42 রিটার্ন করবে। এরপর, Futures.addCallback() ব্যবহার করে আমরা সফল হলে একটি SuccessCallback এবং ত্রুটির ক্ষেত্রে একটি FailureCallback দিয়ে ফিউচারের ফলাফল প্রসেস করেছি।
Futures.transform() এবং Futures.addCallback() এর তুলনা
| ফিচার | Futures.transform() | Futures.addCallback() |
|---|---|---|
| উদ্দেশ্য | ফিউচারের মান পরিবর্তন বা প্রসেস করা | ফিউচারের ফলাফল পাওয়ার পর সফল বা ব্যর্থ কলব্যাক করা |
| প্রক্রিয়া | একটি নতুন ফিউচার রিটার্ন করে | একটি কলব্যাক অ্যাড করা, যা সফল বা ব্যর্থ হলে ট্রিগার হয় |
| ব্যবহারের ধরন | একক অপারেশন প্রসেস করার জন্য | সফল বা ব্যর্থ ফলাফল গ্রহণ এবং প্রতিক্রিয়া জানানো |
সারাংশ
Guava লাইব্রেরির Futures.transform() এবং Futures.addCallback() মেথড দুটি ফিউচার এর সাথে কাজ করার জন্য ব্যবহৃত হয়। Futures.transform() একটি ফিউচার থেকে নতুন একটি ফিউচার তৈরি করে, যেখানে আপনি কোনো মান পরিবর্তন বা প্রসেস করতে পারেন। অন্যদিকে, Futures.addCallback() ফিউচারের ফলাফল পাওয়ার পর সফল বা ব্যর্থ হওয়ার ক্ষেত্রে কলব্যাক অ্যাড করতে ব্যবহৃত হয়, যা অ্যাসিঙ্ক্রোনাস প্রোগ্রামিংয়ের জন্য উপকারী। দুটি মেথডই অ্যাসিঙ্ক্রোনাস প্রোগ্রামিংয়ের কার্যকারিতা বৃদ্ধি করে এবং কাজের ফ্লো আরও সহজ এবং কার্যকরী করে।
গুয়াভা (Guava) লাইব্রেরি জাভাতে কনকারেন্সি ম্যানেজমেন্ট এবং পারফরমেন্স অপটিমাইজেশন বিষয়ক বিভিন্ন শক্তিশালী টুল এবং কনসেপ্ট প্রদান করে। এসব টুলের মাধ্যমে আপনি আপনার অ্যাপ্লিকেশনের কার্যক্ষমতা উন্নত করতে পারেন এবং একাধিক থ্রেডের মধ্যে কাজের বিভাজন সঠিকভাবে পরিচালনা করতে পারবেন। এখানে কিছু গুরুত্বপূর্ণ বৈশিষ্ট্য এবং তাদের ব্যবহার তুলে ধরা হলো।
Concurrency Management
গুয়াভা কনকারেন্সি ম্যানেজমেন্টে বিভিন্ন উপকারি ক্লাস প্রদান করে, যা মাল্টি-থ্রেডিং অ্যাপ্লিকেশনগুলির জন্য অত্যন্ত গুরুত্বপূর্ণ। এর মধ্যে অন্যতম হল ListenableFuture, ListeningExecutorService, এবং Service।
১. ListenableFuture এবং ListeningExecutorService
ListenableFuture এবং ListeningExecutorService জাভার ডিফল্ট Future এবং ExecutorService এর উন্নত সংস্করণ। এগুলো মাল্টি-থ্রেডিং অ্যাপ্লিকেশনগুলির মধ্যে কাজের ফলাফল প্রাপ্তি এবং কনকারেন্ট টাস্ক পরিচালনার জন্য ব্যবহৃত হয়। ListenableFuture আপনি যখন কোন অ্যাসিঙ্ক্রোনাস অপারেশন চালাচ্ছেন তখন ব্যবহার করতে পারেন, এবং ListeningExecutorService এর মাধ্যমে আপনি সহজেই থ্রেডপুলে কাজ পরিচালনা করতে পারেন।
উদাহরণ:
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.ListeningExecutorService;
import com.google.common.util.concurrent.MoreExecutors;
import com.google.common.util.concurrent.Futures;
import java.util.concurrent.Executors;
import java.util.concurrent.Callable;
public class ConcurrencyExample {
public static void main(String[] args) throws Exception {
// ExecutorService তৈরি করা
ListeningExecutorService service = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(10));
// Callable টাস্ক
Callable<String> task = () -> {
Thread.sleep(1000);
return "Task Completed";
};
// ListenableFuture তৈরি করা
ListenableFuture<String> future = service.submit(task);
// Callback যোগ করা
Futures.addCallback(future, new com.google.common.util.concurrent.FutureCallback<String>() {
@Override
public void onSuccess(String result) {
System.out.println("Result: " + result);
}
@Override
public void onFailure(Throwable t) {
System.err.println("Error: " + t.getMessage());
}
}, service);
// ExecutorService বন্ধ করা
service.shutdown();
}
}
এখানে, ListenableFuture এবং Futures.addCallback() ব্যবহার করা হয়েছে, যা টাস্কের ফলাফল পাওয়ার পর কিছু কাজ করতে সহায়ক।
২. Service
গুয়াভা Service ইন্টারফেসটি বিশেষভাবে এমন সিস্টেম বা পরিষেবাগুলির জন্য ব্যবহৃত হয় যেখানে একটি সুনির্দিষ্ট জীবনচক্রের প্রয়োজন। Service ইন্টারফেসের মাধ্যমে আপনি একটি পরিষেবা শুরু, স্থগিত বা বন্ধ করতে পারেন।
উদাহরণ:
import com.google.common.util.concurrent.AbstractService;
public class MyService extends AbstractService {
@Override
protected void doStart() {
System.out.println("Service Started");
notifyStarted();
}
@Override
protected void doStop() {
System.out.println("Service Stopped");
notifyStopped();
}
public static void main(String[] args) {
MyService service = new MyService();
service.startAsync().awaitRunning();
service.stopAsync();
}
}
এখানে AbstractService এর মাধ্যমে একটি সিম্পল সার্ভিস তৈরি করা হয়েছে, যা doStart() এবং doStop() মেথড ব্যবহার করে সার্ভিসের জীবনচক্র পরিচালনা করে।
Performance Optimization
গুয়াভা লাইব্রেরি পারফরমেন্স অপটিমাইজেশনেও অনেক সহায়ক ফিচার প্রদান করে। এর মধ্যে কিছু গুরুত্বপূর্ণ উপাদান হল Cache, ListenableFuture, এবং ImmutableCollections।
১. Cache
গুয়াভা Cache কনটেইনার প্রোভাইড করে, যা দ্রুত অ্যাক্সেসের জন্য ডেটা সংরক্ষণ করতে সহায়ক। এটি বিশেষ করে ডেটা ক্যাশিং এবং ক্যাশিং স্ট্রাটেজির জন্য ব্যবহৃত হয়, যেমন Least Recently Used (LRU) ক্যাশিং স্ট্রাটেজি। Cache আপনার অ্যাপ্লিকেশনের পারফরমেন্স উন্নত করতে সহায়ক, কারণ এটি পুনরায় গণনা বা পুনরায় ডেটা অনুসন্ধানের প্রয়োজনীয়তা কমিয়ে দেয়।
উদাহরণ:
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import java.util.concurrent.TimeUnit;
public class CacheExample {
public static void main(String[] args) {
// Cache তৈরি করা
Cache<String, String> cache = CacheBuilder.newBuilder()
.expireAfterWrite(10, TimeUnit.MINUTES)
.maximumSize(100)
.build();
// Cache এ মান রাখা
cache.put("key1", "value1");
cache.put("key2", "value2");
// Cache থেকে মান প্রাপ্তি
System.out.println("Key1: " + cache.getIfPresent("key1"));
System.out.println("Key2: " + cache.getIfPresent("key2"));
}
}
এখানে CacheBuilder ব্যবহার করে একটি ক্যাশ তৈরি করা হয়েছে যা নির্দিষ্ট সময়ের পরে ডেটা মুছে ফেলবে এবং একটি সর্বাধিক সাইজের সীমা থাকবে।
২. ImmutableCollections
গুয়াভা ImmutableCollections ব্যবহার করে আপনাকে মিউটেবল কন্টেইনারের পরিবর্তে অপরিবর্তনীয় কন্টেইনার তৈরি করতে সহায়ক হয়। এটি থ্রেড সেফ এবং পারফরমেন্স অপটিমাইজেশন করতে সহায়ক।
উদাহরণ:
import com.google.common.collect.ImmutableList;
public class ImmutableCollectionsExample {
public static void main(String[] args) {
// ImmutableList তৈরি করা
ImmutableList<String> list = ImmutableList.of("apple", "banana", "cherry");
// ImmutableList এর মান দেখা
System.out.println("Immutable List: " + list);
}
}
এখানে, ImmutableList ব্যবহার করে একটি অপরিবর্তনীয় লিস্ট তৈরি করা হয়েছে। এটি আরও দ্রুত এবং নিরাপদ অ্যাক্সেস নিশ্চিত করে।
সারাংশ
গুয়াভা (Guava) লাইব্রেরির কনকারেন্সি ম্যানেজমেন্ট এবং পারফরমেন্স অপটিমাইজেশন টুলগুলি আপনাকে মাল্টি-থ্রেডিং অ্যাপ্লিকেশনগুলি সহজে পরিচালনা করতে এবং উচ্চ পারফরমেন্স নিশ্চিত করতে সহায়ক। ListenableFuture এবং ListeningExecutorService মাল্টি-থ্রেডিং কনটেক্সটে অ্যাসিঙ্ক্রোনাস টাস্ক পরিচালনা করতে সাহায্য করে, Cache দ্রুত ডেটা অ্যাক্সেসের জন্য ক্যাশিং সমাধান প্রদান করে, এবং ImmutableCollections থ্রেড সেফ এবং অপটিমাইজড ডেটা স্ট্রাকচার প্রদান করে। এসব টুলের মাধ্যমে আপনার অ্যাপ্লিকেশন আরও কার্যকরী এবং স্কেলেবল হতে পারে।
Read more