JavaFX Concurrency এবং Task Management হল JavaFX অ্যাপ্লিকেশনগুলিতে ব্যাকগ্রাউন্ড থ্রেড বা দীর্ঘকালীন অপারেশনগুলি চালানোর জন্য ব্যবহৃত গুরুত্বপূর্ণ ফিচার। JavaFX-এর Concurrency ব্যবস্থাপনা আপনাকে UI থ্রেডের সাথে ব্যাকগ্রাউন্ড কাজগুলিকে নিরাপদভাবে পরিচালনা করতে সহায়তা করে। এটি অ্যাপ্লিকেশনটিকে আরও কার্যকরী এবং প্রতিক্রিয়া-ক্ষম (responsive) বানায়।
JavaFX-এ কনকারেন্সি সাধারণত দুটি প্রধান উপাদান দ্বারা পরিচালিত হয়:
- Task: ব্যাকগ্রাউন্ডে চলতে থাকা কাজ বা লম্বা সময়ের জন্য চলতে থাকা অপারেশন।
- Service: নির্দিষ্ট কাজ সম্পাদন করতে পারমাণবিক ও পুনরাবৃত্তি করতে সক্ষম একটি থ্রেড-সেভি কাজ ব্যবস্থাপনা।
JavaFX Concurrency এবং Task Management
1. Task Class
Task ক্লাস JavaFX-এ একটি Runnable এর উন্নত সংস্করণ যা ব্যাকগ্রাউন্ড থ্রেডে কাজ করে এবং UI থ্রেডের সাথে নিরাপদভাবে যোগাযোগ করে। এটি খুবই উপকারী যখন আপনি ইউজার ইন্টারফেসে কোনো কাজের ফলাফল প্রদর্শন করতে চান, যেমন লোডিং ইন্ডিকেটর বা প্রগ্রেস বার।
Task ব্যবহার উদাহরণ:
import javafx.application.Application;
import javafx.concurrent.Task;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
import javafx.scene.control.ProgressBar;
public class TaskExample extends Application {
@Override
public void start(Stage primaryStage) {
// একটি প্রগ্রেস বার তৈরি করা
ProgressBar progressBar = new ProgressBar();
progressBar.setProgress(-1.0); // অজ্ঞাত প্রগ্রেস মান
// একটি Task তৈরি করা
Task<Void> task = new Task<Void>() {
@Override
protected Void call() throws Exception {
// ব্যাকগ্রাউন্ড থ্রেডে কিছু কাজ করা
for (int i = 1; i <= 100; i++) {
if (isCancelled()) {
break;
}
updateProgress(i, 100); // প্রগ্রেস আপডেট করা
Thread.sleep(50); // সিমুলেটেড ডিলে
}
return null;
}
};
// প্রগ্রেস আপডেট UI থ্রেডে পাঠানোর জন্য
progressBar.progressProperty().bind(task.progressProperty());
// বাটনে Task শুরু করার জন্য হ্যান্ডলার
Button btnStart = new Button("Start Task");
btnStart.setOnAction(e -> new Thread(task).start()); // Task শুরু করা
// StackPane লেআউট তৈরি করা
StackPane root = new StackPane();
root.getChildren().addAll(progressBar, btnStart);
// Scene তৈরি এবং সেট করা
Scene scene = new Scene(root, 300, 250);
primaryStage.setTitle("JavaFX Task Example");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
এখানে কী হচ্ছে?
- Task:
Taskক্লাসেরcall()মেথডে ব্যাকগ্রাউন্ড কাজটি সম্পাদিত হচ্ছে (যেমন একটি লুপের মাধ্যমে প্রগ্রেস আপডেট করা)। - ProgressBar:
ProgressBarইউআই উপাদানটি ব্যবহার করে আমরা প্রগ্রেস দেখাচ্ছি।progressProperty().bind(task.progressProperty())এর মাধ্যমে ব্যাকগ্রাউন্ড কাজের প্রগ্রেস UI-তে প্রদর্শিত হচ্ছে। - Threading:
new Thread(task).start()লাইনটি ব্যাকগ্রাউন্ড থ্রেডেtaskচালু করে, যাতে UI থ্রেড ব্লক না হয়।
2. Service Class
Service ক্লাস একটি বিশেষ ধরনের কনকারেন্ট কাজ পরিচালনা করার জন্য ব্যবহৃত হয় যা পুনরাবৃত্তি করা যেতে পারে এবং সেগুলি সম্পূর্ণ থ্রেড-পুল ব্যবস্থাপনা করে। এটি সাধারণত নিয়মিত কাজগুলি (যেমন ডাটাবেস কল বা সার্ভার থেকে ডেটা ফেচ করা) পরিচালনার জন্য ব্যবহৃত হয়।
Service ব্যবহার উদাহরণ:
import javafx.application.Application;
import javafx.concurrent.Service;
import javafx.concurrent.Task;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
import javafx.scene.control.ProgressBar;
public class ServiceExample extends Application {
@Override
public void start(Stage primaryStage) {
// একটি প্রগ্রেস বার তৈরি করা
ProgressBar progressBar = new ProgressBar();
progressBar.setProgress(0);
// একটি Service তৈরি করা
Service<Void> service = new Service<Void>() {
@Override
protected Task<Void> createTask() {
return new Task<Void>() {
@Override
protected Void call() throws Exception {
for (int i = 1; i <= 100; i++) {
if (isCancelled()) {
break;
}
updateProgress(i, 100); // প্রগ্রেস আপডেট করা
Thread.sleep(50); // সিমুলেটেড ডিলে
}
return null;
}
};
}
};
// Service-এর প্রগ্রেস বার সাথে বেঁধে দেওয়া
progressBar.progressProperty().bind(service.progressProperty());
// বাটনে Service শুরু করার জন্য হ্যান্ডলার
Button btnStart = new Button("Start Service");
btnStart.setOnAction(e -> service.start()); // Service শুরু করা
// StackPane লেআউট তৈরি করা
StackPane root = new StackPane();
root.getChildren().addAll(progressBar, btnStart);
// Scene তৈরি এবং সেট করা
Scene scene = new Scene(root, 300, 250);
primaryStage.setTitle("JavaFX Service Example");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
এখানে কী হচ্ছে?
- Service:
Serviceক্লাসেরcreateTask()মেথডেTaskতৈরি হচ্ছে। এটি ডাটা ফেচিং বা অন্য ব্যাকগ্রাউন্ড কাজ পরিচালনা করতে পারে। - ProgressBar:
ProgressBarএখানে ব্যাকগ্রাউন্ড কাজের প্রগ্রেস দেখানোর জন্য ব্যবহৃত হচ্ছে।progressProperty().bind(service.progressProperty())এর মাধ্যমেProgressBar-এ প্রগ্রেস আপডেট হচ্ছে। - Service.start():
service.start()কল করে ব্যাকগ্রাউন্ড কাজটি চালানো হচ্ছে।
JavaFX Concurrency: Task এবং Service এর মধ্যে পার্থক্য
- Task:
Taskসাধারণত একক কাজের জন্য ব্যবহৃত হয়, যেমন একটি বড় অপারেশন (ফাইল ডাউনলোড, ডাটা প্রসেসিং) যা UI থ্রেডের বাইরে চলবে।- এটি
RunnableবাCallableএর একটি উন্নত সংস্করণ যা UI থ্রেডের সাথে নিরাপদভাবে যোগাযোগ করতে পারে।
- Service:
Serviceএকাধিক কাজের জন্য ব্যবহৃত হয়, এবং এটি থ্রেড-পুল ব্যবস্থাপনা সরবরাহ করে। এটি সাধারণত পুনরাবৃত্তি কাজ বা দীর্ঘকালীন পরিষেবা (যেমন ওয়েব সার্ভিস কল, ডেটাবেস আপডেট) পরিচালনা করতে ব্যবহৃত হয়।Serviceএমন কাজগুলো পরিচালনা করে যা পুনরাবৃত্তি করা যায় এবং একাধিক কাজ পরিচালনা করার জন্য তৈরি।
Concurrency-এর জন্য কিছু গুরুত্বপূর্ণ পদ্ধতি:
updateProgress(double workDone, double totalWork): ব্যাকগ্রাউন্ড থ্রেড থেকে প্রগ্রেস আপডেট করতে ব্যবহৃত হয়।updateMessage(String message): ব্যাকগ্রাউন্ড থ্রেড থেকে বার্তা পাঠাতে ব্যবহৃত হয়, যা UI-তে দেখানো যেতে পারে।isCancelled(): ব্যাকগ্রাউন্ড কাজটি ক্যানসেল করা হয়েছে কিনা তা পরীক্ষা করার জন্য ব্যবহৃত হয়।
সারাংশ:
JavaFX-এর Concurrency এবং Task Management ব্যবস্থাপনা UI থ্রেডের বাইরে দীর্ঘকালীন কাজ সম্পাদন করতে ব্যবহৃত হয়, যা অ্যাপ্লিকেশনকে প্রতিক্রিয়া-ক্ষম এবং কার্যকরী রাখে। Task ব্যাকগ্রাউন্ড কাজ সম্পাদন করতে ব্যবহৃত হয়, এবং Service পুনরাবৃত্তি কাজ পরিচালনা করে থ্রেড-পুল ব্যবস্থাপনা দিয়ে। এগুলি আপনাকে UI-তে রেসপন্সিভ অ্যানিমেশন এবং প্রগ্রেস দেখানোর মতো কার্যকরী উপায় প্রদান করে।
JavaFX এ, UI থ্রেডে কাজ করার সময় একটি সমস্যা দেখা দিতে পারে যখন দীর্ঘ সময়ের জন্য ব্লকিং অপারেশন (যেমন ডেটাবেস অ্যাক্সেস, ফাইল আই /ও অপারেশন, বা নেটওয়ার্ক রিকুয়েস্ট) চলতে থাকে। এর ফলে ইউজার ইন্টারফেস (UI) "হ্যাং" হয়ে যেতে পারে, যা একটি খারাপ ব্যবহারকারীর অভিজ্ঞতা তৈরি করে। JavaFX এ এই সমস্যা এড়ানোর জন্য কনকারেন্সি মডেল তৈরি করা হয়েছে যা বিভিন্ন থ্রেডে কাজ করার জন্য একটি সুসংগঠিত উপায় সরবরাহ করে।
JavaFX এর কনকারেন্সি মডেলটি এক্সিকিউশন থ্রেড এবং টাস্কের মধ্যে যোগাযোগের জন্য তিনটি প্রধান উপাদান ব্যবহার করে:
- UI Thread (Application Thread): এটি JavaFX অ্যাপ্লিকেশনের প্রধান থ্রেড যেখানে UI উপাদান তৈরি এবং প্রদর্শিত হয়। আপনি UI উপাদান কেবলমাত্র এই থ্রেডের মাধ্যমে পরিচালনা করতে পারেন।
- Worker Threads (Background Threads): এই থ্রেডগুলি দীর্ঘ-running কাজ (যেমন নেটওয়ার্ক রিকুয়েস্ট বা ফাইল অপারেশন) করতে ব্যবহৃত হয়। এসব থ্রেড UI থ্রেডে কোন পরিবর্তন করতে পারে না, তবে তারা UI থ্রেডের সাথে যোগাযোগ করতে পারে।
- JavaFX
TaskএবংService: JavaFX এর মধ্যেTaskএবংServiceক্লাসগুলি বিশেষভাবে কনকারেন্সি ম্যানেজমেন্টের জন্য ব্যবহৃত হয়।
JavaFX কনকারেন্সি মডেলের মূল উপাদানসমূহ
1. Worker Threads (ব্যাকগ্রাউন্ড থ্রেড)
JavaFX UI থ্রেডের পাশাপাশি ব্যাকগ্রাউন্ড থ্রেডে কাজ করতে হলে, আপনাকে সেই থ্রেডে কাজের জন্য Task বা Service ব্যবহার করতে হবে। UI থ্রেডে সরাসরি ব্যাকগ্রাউন্ড কাজ করা সম্ভব নয়, তাই এসব ক্লাস UI থ্রেডের থেকে ব্যাকগ্রাউন্ড থ্রেডে কাজ চালানোর সুযোগ দেয় এবং UI-তে পরিবর্তন আনতে সাহায্য করে।
2. Task Class
Task ক্লাস হল একটি Worker সাবক্লাস যা ব্যাকগ্রাউন্ড কাজের জন্য ব্যবহৃত হয় এবং UI থ্রেডে ফলাফল বা স্ট্যাটাস পাঠানোর জন্য সেট করা যেতে পারে।
Task ক্লাসের সাহায্যে আপনি ব্যাকগ্রাউন্ডে কাজ চালাতে পারেন এবং তার ফলাফল UI থ্রেডে পাঠাতে পারেন।
3. Service Class
Service ক্লাস হল Task এর একটি উন্নত সংস্করণ, যা পুনরাবৃত্ত কাজ বা লং রানিং টাস্কের জন্য উপযুক্ত। Service ক্লাসের মধ্যে একটি অতিরিক্ত সুবিধা হল এটি একাধিক থ্রেডে পুনরাবৃত্তি করা যেতে পারে।
JavaFX Task Example
নিচে একটি উদাহরণ দেওয়া হয়েছে, যেখানে Task ব্যবহার করে ব্যাকগ্রাউন্ডে কাজ চলছে এবং UI থ্রেডে ফলাফল আপডেট করা হচ্ছে।
import javafx.application.Application;
import javafx.concurrent.Task;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
public class ConcurrencyExample extends Application {
@Override
public void start(Stage primaryStage) {
Label label = new Label("Processing...");
// Task তৈরি
Task<Void> task = new Task<Void>() {
@Override
protected Void call() throws Exception {
for (int i = 0; i < 100; i++) {
// কাজ চালিয়ে যাওয়ার সময় স্ট্যাটাস আপডেট
updateMessage("Processing: " + i + "%");
Thread.sleep(50); // 50 মিলি সেকেন্ড বিরতি
}
return null;
}
};
// Task এর মেসেজ আপডেট UI তে দেখানো
label.textProperty().bind(task.messageProperty());
// Task রান করা
Thread thread = new Thread(task);
thread.setDaemon(true);
thread.start();
StackPane root = new StackPane();
root.getChildren().add(label);
Scene scene = new Scene(root, 300, 200);
primaryStage.setScene(scene);
primaryStage.setTitle("JavaFX Concurrency Example");
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
ব্যাখ্যা:
Task<Void>:Taskক্লাস একটি ব্যাকগ্রাউন্ড টাস্ক তৈরি করে যা UI থ্রেডে ফলাফল পাঠাতে পারে।updateMessage(): এটি ব্যাকগ্রাউন্ড থ্রেড থেকে UI থ্রেডে একটি মেসেজ পাঠানোর জন্য ব্যবহৃত হয়। এটি UI তে কাজের প্রগতি দেখায়।textProperty().bind():Taskএর মেসেজ প্রপার্টি UI এর লেবেলটির টেক্সট প্রপার্টির সাথে বেঁধে দেওয়া হয়েছে, যাতে ব্যাকগ্রাউন্ড কাজের স্ট্যাটাস UI তে আপডেট হয়।
JavaFX Service Example
Service ক্লাস ব্যবহার করে, আপনি একটি লং রানিং টাস্কের জন্য একটি পুনরাবৃত্ত কাজ তৈরি করতে পারেন।
import javafx.application.Application;
import javafx.concurrent.Service;
import javafx.concurrent.Task;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
public class ServiceExample extends Application {
@Override
public void start(Stage primaryStage) {
Label label = new Label("Starting...");
// Service তৈরি
Service<Void> service = new Service<Void>() {
@Override
protected Task<Void> createTask() {
return new Task<Void>() {
@Override
protected Void call() throws Exception {
for (int i = 0; i < 100; i++) {
// প্রক্রিয়ার স্ট্যাটাস আপডেট
updateMessage("Processing: " + i + "%");
Thread.sleep(50); // 50 মিলি সেকেন্ড বিরতি
}
return null;
}
};
}
};
// Service এর মেসেজ আপডেট UI তে দেখানো
label.textProperty().bind(service.messageProperty());
// বাটন ক্লিক করলে Service চালানো হবে
Button button = new Button("Start Process");
button.setOnAction(e -> service.start());
StackPane root = new StackPane();
root.getChildren().addAll(label, button);
Scene scene = new Scene(root, 300, 200);
primaryStage.setScene(scene);
primaryStage.setTitle("JavaFX Service Example");
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
ব্যাখ্যা:
Serviceক্লাস: এটি একটি কাজ বা টাস্ক পরিচালনা করে যা পুনরাবৃত্তি করা যেতে পারে।createTask():Serviceএর মাধ্যমে আপনি একটিTaskতৈরি করেন যা ব্যাকগ্রাউন্ডে রান করবে।messageProperty(): একইভাবে,Serviceএর মেসেজ প্রপার্টি UI তে আপডেট হয়।
JavaFX Concurrency Model এর সুবিধা
- UI থ্রেড ব্লক করা থেকে রক্ষা: ব্যাকগ্রাউন্ড থ্রেডে কাজ করার ফলে UI থ্রেড ব্লক হয় না এবং ব্যবহারকারীর অভিজ্ঞতা উন্নত হয়।
- UI-তে প্রগ্রেস বার আপডেট: আপনি সহজেই ব্যাকগ্রাউন্ড কাজের অগ্রগতি UI তে প্রদর্শন করতে পারেন।
TaskএবংServiceক্লাস: এই ক্লাসগুলি পুনরাবৃত্ত কাজ এবং একাধিক টাস্ক ম্যানেজ করতে সাহায্য করে।
JavaFX এর Concurrency Model অত্যন্ত শক্তিশালী এবং ইন্টারেক্টিভ অ্যাপ্লিকেশন তৈরি করার জন্য অত্যন্ত গুরুত্বপূর্ণ। এটি UI থ্রেডে কাজ না করে ব্যাকগ্রাউন্ড থ্রেডে লম্বা-running অপারেশন চালানোর সুবিধা দেয় এবং UI কে সহজেই আপডেট করা সম্ভব করে। Task এবং Service ক্লাসগুলি আপনার অ্যাপ্লিকেশনের কর্মক্ষমতা বৃদ্ধি করতে সহায়ক।
JavaFX-এর Concurrency Model একটি অত্যন্ত গুরুত্বপূর্ণ বিষয়, যা আপনার অ্যাপ্লিকেশনে ব্যাকগ্রাউন্ড অপারেশন পরিচালনার জন্য ব্যবহৃত হয়। JavaFX-এর ইউজার ইন্টারফেস থ্রেড (UI Thread) মূলত ব্যবহারকারীর ইন্টারঅ্যাকশন পরিচালনা করে, এবং এটি ব্লক হতে দেওয়া উচিত নয়। ব্যাকগ্রাউন্ড অপারেশন সম্পাদন করার জন্য Task এবং Service দুটি গুরুত্বপূর্ণ ক্লাস রয়েছে যা ব্যাকগ্রাউন্ডে কাজ চালাতে সাহায্য করে, এবং UI থ্রেডকে ব্লক না করে কাজ সম্পাদন করা যায়।
Task এবং Service কী?
- Task:
Taskহল একটি জেনেরিক ক্লাস যাjavafx.concurrentপ্যাকেজের অধীনে আসে। এটি ব্যাকগ্রাউন্ডে একটি কাজ সম্পাদন করার জন্য ব্যবহৃত হয় এবং ইউজার ইন্টারফেসের সাথে ইন্টারঅ্যাকশন করতেupdateমেথড ব্যবহার করে।- এটি
Runnableইন্টারফেসের মতো কাজ করে, তবে এটি প্রগ্রেস আপডেট, ফলাফল এবং ব্যর্থতার প্রতিবেদন করার জন্য অতিরিক্ত ফিচার সমর্থন করে।
- Service:
Serviceহল একটি আরো উন্নত কনসেপ্ট যা একটি পুনরাবৃত্ত কার্যক্রম (repeated task) পরিচালনার জন্য ব্যবহৃত হয়, যেখানেTaskএকটি একক কার্যক্রমের জন্য ব্যবহৃত হয়।Serviceএকটি নতুনTaskতৈরি করে, এবং এটি ব্যাকগ্রাউন্ডে কাজটি চালাতে সক্ষম।
ব্যাকগ্রাউন্ড অপারেশন পরিচালনা করার জন্য Task এবং Service ব্যবহারের উদাহরণ
১. Task ব্যবহার করে ব্যাকগ্রাউন্ড অপারেশন
নিচে একটি উদাহরণ দেওয়া হয়েছে যেখানে একটি Task ব্যবহার করে ব্যাকগ্রাউন্ডে কাজ করা হচ্ছে এবং UI থ্রেডে তার প্রগ্রেস এবং রেজাল্ট আপডেট করা হচ্ছে।
import javafx.application.Application;
import javafx.concurrent.Task;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ProgressBar;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class TaskExample extends Application {
@Override
public void start(Stage primaryStage) {
// UI উপাদান তৈরি
Button startButton = new Button("Start Task");
ProgressBar progressBar = new ProgressBar(0);
// Task তৈরি
Task<Void> backgroundTask = new Task<Void>() {
@Override
protected Void call() throws Exception {
// কাজের প্রগ্রেস আপডেট করা
for (int i = 0; i <= 100; i++) {
if (isCancelled()) {
break;
}
updateProgress(i, 100); // প্রগ্রেস আপডেট করা
Thread.sleep(100); // কিছু সময়ের জন্য ঘুমানো
}
return null;
}
};
// প্রগ্রেস আপডেট করতে Task এর সাথে UI উপাদান বাঁধা
progressBar.progressProperty().bind(backgroundTask.progressProperty());
// বাটনে ক্লিক করলে Task শুরু হবে
startButton.setOnAction(e -> {
new Thread(backgroundTask).start(); // Task ব্যাকগ্রাউন্ডে চালানো
});
// লেআউট সেট করা
VBox vbox = new VBox(10, startButton, progressBar);
Scene scene = new Scene(vbox, 300, 150);
primaryStage.setScene(scene);
primaryStage.setTitle("Task Example");
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
ব্যাখ্যা:
Taskতৈরি করা হয়েছে যা একটি ব্যাকগ্রাউন্ড অপারেশন পরিচালনা করবে। এটি প্রতি সেকেন্ডে প্রগ্রেস আপডেট করবে এবংupdateProgress()মেথড ব্যবহার করে প্রগ্রেস পরিবর্তন করবে।ProgressBarUI উপাদানকেTaskএর প্রগ্রেসের সাথে বাঁধা দেওয়া হয়েছে (progressProperty().bind()), যাতে প্রগ্রেস বার আপডেট হয়।- বাটন ক্লিক করলে একটি নতুন থ্রেড শুরু হবে যা
Taskচালাবে, এবং UI থ্রেড ব্লক হবে না।
২. Service ব্যবহার করে ব্যাকগ্রাউন্ড অপারেশন
যখন আপনার একটি পুনরাবৃত্তি কাজ করতে হয় বা একটি দীর্ঘ-running ব্যাকগ্রাউন্ড অপারেশন চালাতে হয়, তখন Service ক্লাস ব্যবহার করা হয়। এখানে একটি Service ব্যবহার করে ব্যাকগ্রাউন্ড অপারেশন দেখানো হল।
import javafx.application.Application;
import javafx.concurrent.Service;
import javafx.concurrent.Task;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ProgressBar;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class ServiceExample extends Application {
@Override
public void start(Stage primaryStage) {
// UI উপাদান তৈরি
Button startButton = new Button("Start Service");
ProgressBar progressBar = new ProgressBar(0);
// Service তৈরি
Service<Void> service = new Service<Void>() {
@Override
protected Task<Void> createTask() {
return new Task<Void>() {
@Override
protected Void call() throws Exception {
for (int i = 0; i <= 100; i++) {
if (isCancelled()) {
break;
}
updateProgress(i, 100); // প্রগ্রেস আপডেট করা
Thread.sleep(100); // কিছু সময়ের জন্য ঘুমানো
}
return null;
}
};
}
};
// প্রগ্রেস আপডেট করতে Service এর সাথে UI উপাদান বাঁধা
progressBar.progressProperty().bind(service.progressProperty());
// বাটনে ক্লিক করলে Service শুরু হবে
startButton.setOnAction(e -> service.start()); // Service চালানো
// লেআউট সেট করা
VBox vbox = new VBox(10, startButton, progressBar);
Scene scene = new Scene(vbox, 300, 150);
primaryStage.setScene(scene);
primaryStage.setTitle("Service Example");
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
ব্যাখ্যা:
Serviceতৈরি করা হয়েছে, এবংcreateTask()মেথডের মাধ্যমে একটিTaskতৈরি করা হয়।Taskএর ভিতরে ব্যাকগ্রাউন্ড কাজগুলি করা হচ্ছে এবংupdateProgress()মেথড দিয়ে প্রগ্রেস আপডেট করা হচ্ছে।progressProperty()ব্যবহার করে প্রগ্রেস বার UI উপাদানকেServiceএর প্রগ্রেসের সাথে বাঁধা দেওয়া হয়েছে।service.start()দ্বারাServiceচালানো হচ্ছে।
Task এবং Service এর মধ্যে পার্থক্য:
| ক্যারেক্টারিস্টিক | Task | Service |
|---|---|---|
| ব্যবহার | একক কাজের জন্য ব্যবহৃত | পুনরাবৃত্তি কাজের জন্য ব্যবহৃত |
| ব্যাকগ্রাউন্ড থ্রেড | নিজেই থ্রেড তৈরি করে | নিজে থ্রেড তৈরি করে এবং কাজের জন্য Task তৈরি করে |
| স্টার্টিং | new Thread(task).start(); | service.start() |
| অবস্থা | একবারে একটি কাজ পরিচালনা করে | একাধিক বার চালানো যায় |
- Task এবং Service হল JavaFX-এর দুটি গুরুত্বপূর্ণ ক্লাস, যা ব্যাকগ্রাউন্ডে অপারেশন চালানোর জন্য ব্যবহৃত হয়।
Taskএকক কাজ পরিচালনা করতে ব্যবহৃত হয়, এবংServiceপুনরাবৃত্তি কাজের জন্য ব্যবহৃত হয়। - এই ক্লাসগুলি ব্যাকগ্রাউন্ড অপারেশন চালাতে সাহায্য করে এবং ইউজার ইন্টারফেস থ্রেডকে ব্লক না করে ইউজার ইন্টারঅ্যাকশনের মাধ্যমে স্মুথ ও সাড়া দানযোগ্য অ্যাপ্লিকেশন তৈরি করতে সাহায্য করে।
- Task এবং Service ক্লাস ব্যবহার করে আপনি সহজেই ব্যাকগ্রাউন্ড কাজ চালাতে পারবেন এবং প্রগ্রেস/ফলাফল ইউজার ইন্টারফেসে প্রদর্শন করতে পারবেন।
Platform.runLater() মেথডটি JavaFX তে ব্যবহৃত হয় যখন আপনি UI থ্রেডে কাজ করতে চান, কিন্তু আপনি অন্য কোন থ্রেড থেকে UI উপাদানগুলির সাথে ইন্টারঅ্যাকশন করছেন। JavaFX অ্যাপ্লিকেশনগুলো single-threaded থাকে এবং UI-র সমস্ত পরিবর্তন JavaFX Application Thread (UI Thread) এ ঘটতে হয়। তবে, আপনি যদি কোনও ব্যাকগ্রাউন্ড থ্রেড (যেমন, একটি নতুন থ্রেড বা Task ক্লাস) থেকে UI-র কোন উপাদান পরিবর্তন করতে চান, তবে Platform.runLater() ব্যবহার করতে হবে। এটি নিশ্চিত করে যে UI সংশ্লিষ্ট কাজগুলি UI থ্রেডে সঠিকভাবে সম্পাদিত হবে।
Platform.runLater() মেথডের কাজ:
- এটি একটি Runnable অবজেক্ট নেয় এবং সেই কোডটি JavaFX Application Thread এ রান করায়।
- যেহেতু JavaFX অ্যাপ্লিকেশন থ্রেড UI উপাদানগুলির সাথে কাজ করার জন্য একমাত্র থ্রেড, তাই ব্যাকগ্রাউন্ড থ্রেড থেকে UI-এ পরিবর্তন করতে
Platform.runLater()ব্যবহার করা প্রয়োজন।
Platform.runLater() এর সাধারণ ব্যবহার:
1. Basic Example:
এই উদাহরণে, ব্যাকগ্রাউন্ড থ্রেড থেকে UI-তে একটি বার্তা আপডেট করা হচ্ছে।
import javafx.application.Application;
import javafx.application.Platform;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
public class PlatformRunLaterExample extends Application {
@Override
public void start(Stage primaryStage) {
// UI-তে একটি লেবেল তৈরি
Label label = new Label("Initial Text");
// StackPane layout
StackPane root = new StackPane();
root.getChildren().add(label);
// Scene তৈরি এবং সেট করা
Scene scene = new Scene(root, 300, 250);
primaryStage.setTitle("Platform.runLater() Example");
primaryStage.setScene(scene);
primaryStage.show();
// নতুন থ্রেড তৈরি করা
new Thread(() -> {
try {
// কিছু কাজ সম্পন্ন করার জন্য দেরী করা
Thread.sleep(2000);
// UI-তে কিছু পরিবর্তন করার জন্য Platform.runLater() ব্যবহার করা
Platform.runLater(() -> {
label.setText("Text Updated from Background Thread");
});
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
}
public static void main(String[] args) {
launch(args);
}
}
এখানে কী হচ্ছে?
- UI Thread এ একটি লেবেল তৈরি করা হয়েছে।
- একটি নতুন থ্রেড তৈরি করা হয়েছে যা
Thread.sleep(2000)দিয়ে 2 সেকেন্ড বিরতি নিচ্ছে। - 2 সেকেন্ড পরে,
Platform.runLater()ব্যবহার করে UI থ্রেডে লেবেলের টেক্সট পরিবর্তন করা হচ্ছে। এতে UI থ্রেডে সঠিকভাবে কাজ হচ্ছে এবং "Text Updated from Background Thread" বার্তা প্রদর্শিত হচ্ছে।
2. Background Task with UI Updates Example:
এখানে একটি ব্যাকগ্রাউন্ড টাস্কের মাধ্যমে ডেটা প্রসেস করা হচ্ছে এবং সেই ডেটার সাথে UI আপডেট করা হচ্ছে।
import javafx.application.Application;
import javafx.application.Platform;
import javafx.concurrent.Task;
import javafx.scene.Scene;
import javafx.scene.control.ProgressBar;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
public class BackgroundTaskWithUIExample extends Application {
@Override
public void start(Stage primaryStage) {
// প্রগ্রেস বার তৈরি করা
ProgressBar progressBar = new ProgressBar(0);
// StackPane layout
StackPane root = new StackPane();
root.getChildren().add(progressBar);
// Scene তৈরি এবং সেট করা
Scene scene = new Scene(root, 300, 250);
primaryStage.setTitle("Background Task with UI Updates");
primaryStage.setScene(scene);
primaryStage.show();
// ব্যাকগ্রাউন্ড টাস্ক তৈরি করা
Task<Void> task = new Task<Void>() {
@Override
protected Void call() throws Exception {
for (int i = 0; i <= 100; i++) {
// প্রগ্রেস আপডেট করার জন্য Platform.runLater() ব্যবহার করা
final int progress = i;
Platform.runLater(() -> progressBar.setProgress(progress / 100.0));
// কিছু কাজ সম্পন্ন করার জন্য দেরী করা
Thread.sleep(50);
}
return null;
}
};
// টাস্ক চালানো
new Thread(task).start();
}
public static void main(String[] args) {
launch(args);
}
}
এখানে কী হচ্ছে?
- একটি ProgressBar তৈরি করা হয়েছে যা ব্যবহারকারীকে কিছু কাজ চলমান থাকার সময় আপডেট দেখাবে।
- একটি ব্যাকগ্রাউন্ড Task তৈরি করা হয়েছে যা 0 থেকে 100 পর্যন্ত প্রগ্রেস আপডেট করবে।
Platform.runLater()ব্যবহার করে ব্যাকগ্রাউন্ড থ্রেড থেকে UI-তে প্রগ্রেস আপডেট করা হচ্ছে, যাতে UI থ্রেডে সঠিকভাবে এটি দেখানো যায়।
Platform.runLater() এর প্রয়োজনীয়তা
- UI Thread Safety: JavaFX অ্যাপ্লিকেশন থ্রেডে UI উপাদানগুলির সাথে ইন্টারঅ্যাকশন করার জন্য নিশ্চিতভাবে UI Thread এ কাজ করতে হবে। অন্যথায়
IllegalStateExceptionহতে পারে। - Concurrency: ব্যাকগ্রাউন্ড থ্রেডের মাধ্যমে লম্বা সময়ের কাজ সম্পাদন করতে গেলে, UI থ্রেডে কোনো লক বা ফ্রিজিং না ঘটে, সে কারণে UI-কে আপডেট করতে
Platform.runLater()ব্যবহার করা হয়।
Platform.runLater() এর অতিরিক্ত ব্যবহার
- UI Updates: যখন আপনি ব্যাকগ্রাউন্ড থ্রেডে কিছু কাজ করেন, এবং সেই কাজের ফলাফল UI-তে দেখাতে চান, তখন
Platform.runLater()ব্যবহার করা হয়। - Thread Communication: ব্যাকগ্রাউন্ড থ্রেড এবং UI থ্রেডের মধ্যে ডেটা পাঠানোর জন্য এটি ব্যবহৃত হতে পারে।
- Animation Updates: কোনো অ্যানিমেশন বা টাস্কের ফলাফল UI-তে ধীরে ধীরে আপডেট করতে হলে,
Platform.runLater()ব্যবহার করা হয়।
সারাংশ:
Platform.runLater()মেথডটি JavaFX অ্যাপ্লিকেশনে ব্যাকগ্রাউন্ড থ্রেড থেকে UI থ্রেডে ইভেন্ট বা কাজ পাঠানোর জন্য ব্যবহৃত হয়।- এটি JavaFX অ্যাপ্লিকেশন থ্রেডে UI Components এর সাথে সঠিকভাবে কাজ করার জন্য গুরুত্বপূর্ণ।
JavaFX Multithreading হল এমন একটি প্রক্রিয়া যার মাধ্যমে একাধিক থ্রেডের সাহায্যে অ্যাপ্লিকেশনটি একাধিক কাজ একসাথে করতে সক্ষম হয়। JavaFX মূলত Single Threaded পরিবেশে কাজ করে, যেখানে সমস্ত UI ইভেন্ট এবং অ্যাকশন একটি একক থ্রেড (JavaFX Application Thread) দ্বারা পরিচালিত হয়। তবে, multithreading ব্যবহার করে আপনি ব্যাকগ্রাউন্ডে কম্পিউটেশন বা দীর্ঘমেয়াদী কাজ চালাতে পারেন, যাতে UI থ্রেডের ওপর কোন চাপ না পড়ে এবং ইউজারের ইন্টারফেস স্ন্যাপি থাকে।
JavaFX অ্যাপ্লিকেশনে Multithreading ব্যবহার করার সময় কিছু সেরা অভ্যাস রয়েছে, যা আপনাকে পারফরম্যান্স উন্নত করতে এবং সঠিকভাবে কাজ করার জন্য সহায়তা করবে।
JavaFX Multithreading এর Best Practices
1. UI Thread এবং Worker Thread আলাদা রাখা
JavaFX এর UI Thread শুধুমাত্র UI সম্পর্কিত কাজ পরিচালনা করে এবং এটি ব্লক করা যাবে না। আপনি worker thread ব্যবহার করবেন ব্যাকগ্রাউন্ড কাজ করার জন্য এবং এই থ্রেডটি UI থ্রেডের ওপর কোনও প্রভাব ফেলবে না।
Best Practice: ব্যাকগ্রাউন্ড কাজ করার জন্য Task অথবা Service ক্লাস ব্যবহার করুন এবং UI-এ তথ্য আপডেট করতে Platform.runLater() ব্যবহার করুন।
2. Task বা Service ব্যবহার করা
Task: একটিTaskক্লাস JavaFX-এ ব্যাকগ্রাউন্ড কাজের জন্য ব্যবহৃত হয়, এবং এটি একাধিক স্টেপে কাজ সম্পন্ন করতে সহায়তা করে। এটিrun()মেথডে কাজ করার সময়updateValue()অথবাupdateMessage()মেথড ব্যবহার করে UI থ্রেডের সাথে যোগাযোগ করতে পারে।Service: একটিServiceসাধারণতTaskএর তুলনায় দীর্ঘমেয়াদী কাজের জন্য ব্যবহৃত হয়, যেমন অ্যাসিঙ্ক্রোনাস বা পিরিওডিক কাজ।
Task উদাহরণ:
import javafx.application.Application;
import javafx.application.Platform;
import javafx.concurrent.Task;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
public class MultithreadingExample extends Application {
@Override
public void start(Stage primaryStage) {
Label label = new Label("Processing...");
// Background Task
Task<Void> backgroundTask = new Task<Void>() {
@Override
protected Void call() throws Exception {
// Perform long-running task here
for (int i = 0; i < 10; i++) {
// Simulate work being done
Thread.sleep(500);
// Update the UI (must be done on the JavaFX Application Thread)
final int progress = i + 1;
Platform.runLater(() -> label.setText("Progress: " + progress * 10 + "%"));
}
return null;
}
};
// Start the task on a new thread
new Thread(backgroundTask).start();
StackPane root = new StackPane();
root.getChildren().add(label);
Scene scene = new Scene(root, 300, 200);
primaryStage.setTitle("JavaFX Multithreading Example");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
3. UI Thread থেকে Worker Thread এ নিরাপদভাবে ডেটা স্থানান্তর করা
UI থ্রেডের মধ্যে কোনো কাজ করার জন্য, JavaFX এর Platform.runLater() ব্যবহার করা হয়, যা UI থ্রেডের কাজ পরিচালনা করতে সহায়তা করে। যখন ব্যাকগ্রাউন্ড থ্রেডে কোন কাজ শেষ হয়, তখন UI-তে সেই কাজের ফলাফল দেখাতে Platform.runLater() ব্যবহার করুন।
Best Practice: Platform.runLater() এর মাধ্যমে UI উপাদানগুলির আপডেট করতে হবে।
Platform.runLater(() -> {
// Update UI elements safely from worker thread
label.setText("Task completed!");
});
4. Service ক্লাস ব্যবহার করা
Service ক্লাসটি পুনরাবৃত্তিমূলক কাজের জন্য আদর্শ। এটি asynchronous কাজ পরিচালনা করার জন্য তৈরি এবং UI-তে ফলাফল আপডেট করতে ব্যবহৃত হতে পারে।
Service উদাহরণ:
import javafx.application.Application;
import javafx.concurrent.Service;
import javafx.concurrent.Task;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
public class ServiceExample extends Application {
@Override
public void start(Stage primaryStage) {
Label label = new Label("Starting task...");
Button button = new Button("Start Task");
// Service class to manage background work
Service<Void> service = new Service<Void>() {
@Override
protected Task<Void> createTask() {
return new Task<Void>() {
@Override
protected Void call() throws Exception {
for (int i = 0; i < 10; i++) {
Thread.sleep(500);
final int progress = i + 1;
updateMessage("Progress: " + progress * 10 + "%");
}
return null;
}
};
}
};
// Bind service message to label text
label.textProperty().bind(service.messageProperty());
// Start the service when button is clicked
button.setOnAction(e -> service.restart());
StackPane root = new StackPane();
root.getChildren().addAll(button, label);
Scene scene = new Scene(root, 300, 250);
primaryStage.setTitle("JavaFX Service Example");
primaryStage.setScene(scene);
primaryStage.show();
service.start();
}
public static void main(String[] args) {
launch(args);
}
}
5. Blocking Tasks থেকে বিরত থাকুন
অতিরিক্ত দীর্ঘ সময় নেয়া কোনো কাজ UI থ্রেডে সরাসরি না করার চেষ্টা করুন, কারণ এটি অ্যাপ্লিকেশনকে "ফ্রিজ" করতে পারে। সেক্ষেত্রে ব্যাকগ্রাউন্ড থ্রেড ব্যবহার করুন।
Best Practice:
- যদি কোনো কাজ দীর্ঘ সময় নেয়, সেটি worker thread বা Task ব্যবহার করে করবেন।
- UI থ্রেডে শুধুমাত্র UI সম্পর্কিত কাজ করবেন।
6. Error Handling in Worker Threads
ব্যাকগ্রাউন্ড থ্রেডে যদি কোনো সমস্যা বা exception ঘটে, তবে UI-তে ব্যবহারকারীকে সেটি জানানো প্রয়োজন। JavaFX এর Task বা Service ক্লাসে setOnFailed() ইভেন্ট হ্যান্ডলার ব্যবহার করে এমন exception গুলি হ্যান্ডল করতে পারবেন।
backgroundTask.setOnFailed(event -> {
Throwable exception = backgroundTask.getException();
System.out.println("Error: " + exception.getMessage());
});
7. Thread Pool ব্যবহার করা
কিছু ক্ষেত্রে একাধিক থ্রেড একসাথে চালাতে হতে পারে, যেমন ওয়েব সার্ভিস কল বা মাল্টিপল টাস্ক। এ জন্য ExecutorService এর মতো থ্রেড পুল ব্যবহার করা যেতে পারে।
ExecutorService executor = Executors.newFixedThreadPool(4);
executor.submit(() -> {
// Perform a background task
});
সারাংশ:
- UI Thread এবং Worker Thread আলাদা রাখা প্রয়োজন। JavaFX অ্যাপ্লিকেশনে UI থ্রেডের কাজ শুধুমাত্র UI সম্পর্কিত হতে হবে।
- Task এবং Service ক্লাস ব্যবহার করে ব্যাকগ্রাউন্ড থ্রেডে কাজ পরিচালনা করুন এবং Platform.runLater() ব্যবহার করে UI থ্রেডে সেফলি ডেটা আপডেট করুন।
- Error Handling এবং Thread Pool ব্যবহারের মাধ্যমে কোডকে আরও নিরাপদ এবং দক্ষ করুন।
এই সেরা অভ্যাসগুলো আপনাকে JavaFX অ্যাপ্লিকেশনগুলিতে মাল্টিথ্রেডিং পরিচালনা করতে সাহায্য করবে, যাতে অ্যাপ্লিকেশনটির পারফরম্যান্স উন্নত হয় এবং ইউজারের জন্য স্ন্যাপি ইন্টারফেস নিশ্চিত করা যায়।
Read more