JavaFX Concurrency এবং Task Management হল JavaFX অ্যাপ্লিকেশনগুলিতে ব্যাকগ্রাউন্ড থ্রেড বা দীর্ঘকালীন অপারেশনগুলি চালানোর জন্য ব্যবহৃত গুরুত্বপূর্ণ ফিচার। JavaFX-এর Concurrency ব্যবস্থাপনা আপনাকে UI থ্রেডের সাথে ব্যাকগ্রাউন্ড কাজগুলিকে নিরাপদভাবে পরিচালনা করতে সহায়তা করে। এটি অ্যাপ্লিকেশনটিকে আরও কার্যকরী এবং প্রতিক্রিয়া-ক্ষম (responsive) বানায়।
JavaFX-এ কনকারেন্সি সাধারণত দুটি প্রধান উপাদান দ্বারা পরিচালিত হয়:
Task
ক্লাস JavaFX-এ একটি Runnable
এর উন্নত সংস্করণ যা ব্যাকগ্রাউন্ড থ্রেডে কাজ করে এবং UI থ্রেডের সাথে নিরাপদভাবে যোগাযোগ করে। এটি খুবই উপকারী যখন আপনি ইউজার ইন্টারফেসে কোনো কাজের ফলাফল প্রদর্শন করতে চান, যেমন লোডিং ইন্ডিকেটর বা প্রগ্রেস বার।
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
ক্লাসের call()
মেথডে ব্যাকগ্রাউন্ড কাজটি সম্পাদিত হচ্ছে (যেমন একটি লুপের মাধ্যমে প্রগ্রেস আপডেট করা)।ProgressBar
ইউআই উপাদানটি ব্যবহার করে আমরা প্রগ্রেস দেখাচ্ছি। progressProperty().bind(task.progressProperty())
এর মাধ্যমে ব্যাকগ্রাউন্ড কাজের প্রগ্রেস UI-তে প্রদর্শিত হচ্ছে।new Thread(task).start()
লাইনটি ব্যাকগ্রাউন্ড থ্রেডে task
চালু করে, যাতে 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.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
ক্লাসের createTask()
মেথডে Task
তৈরি হচ্ছে। এটি ডাটা ফেচিং বা অন্য ব্যাকগ্রাউন্ড কাজ পরিচালনা করতে পারে।ProgressBar
এখানে ব্যাকগ্রাউন্ড কাজের প্রগ্রেস দেখানোর জন্য ব্যবহৃত হচ্ছে। progressProperty().bind(service.progressProperty())
এর মাধ্যমে ProgressBar
-এ প্রগ্রেস আপডেট হচ্ছে।service.start()
কল করে ব্যাকগ্রাউন্ড কাজটি চালানো হচ্ছে।Task
সাধারণত একক কাজের জন্য ব্যবহৃত হয়, যেমন একটি বড় অপারেশন (ফাইল ডাউনলোড, ডাটা প্রসেসিং) যা UI থ্রেডের বাইরে চলবে।Runnable
বা Callable
এর একটি উন্নত সংস্করণ যা UI থ্রেডের সাথে নিরাপদভাবে যোগাযোগ করতে পারে।Service
একাধিক কাজের জন্য ব্যবহৃত হয়, এবং এটি থ্রেড-পুল ব্যবস্থাপনা সরবরাহ করে। এটি সাধারণত পুনরাবৃত্তি কাজ বা দীর্ঘকালীন পরিষেবা (যেমন ওয়েব সার্ভিস কল, ডেটাবেস আপডেট) পরিচালনা করতে ব্যবহৃত হয়।Service
এমন কাজগুলো পরিচালনা করে যা পুনরাবৃত্তি করা যায় এবং একাধিক কাজ পরিচালনা করার জন্য তৈরি।updateProgress(double workDone, double totalWork)
: ব্যাকগ্রাউন্ড থ্রেড থেকে প্রগ্রেস আপডেট করতে ব্যবহৃত হয়।updateMessage(String message)
: ব্যাকগ্রাউন্ড থ্রেড থেকে বার্তা পাঠাতে ব্যবহৃত হয়, যা UI-তে দেখানো যেতে পারে।isCancelled()
: ব্যাকগ্রাউন্ড কাজটি ক্যানসেল করা হয়েছে কিনা তা পরীক্ষা করার জন্য ব্যবহৃত হয়।JavaFX-এর Concurrency এবং Task Management ব্যবস্থাপনা UI থ্রেডের বাইরে দীর্ঘকালীন কাজ সম্পাদন করতে ব্যবহৃত হয়, যা অ্যাপ্লিকেশনকে প্রতিক্রিয়া-ক্ষম এবং কার্যকরী রাখে। Task ব্যাকগ্রাউন্ড কাজ সম্পাদন করতে ব্যবহৃত হয়, এবং Service পুনরাবৃত্তি কাজ পরিচালনা করে থ্রেড-পুল ব্যবস্থাপনা দিয়ে। এগুলি আপনাকে UI-তে রেসপন্সিভ অ্যানিমেশন এবং প্রগ্রেস দেখানোর মতো কার্যকরী উপায় প্রদান করে।
JavaFX এ, UI থ্রেডে কাজ করার সময় একটি সমস্যা দেখা দিতে পারে যখন দীর্ঘ সময়ের জন্য ব্লকিং অপারেশন (যেমন ডেটাবেস অ্যাক্সেস, ফাইল আই /ও অপারেশন, বা নেটওয়ার্ক রিকুয়েস্ট) চলতে থাকে। এর ফলে ইউজার ইন্টারফেস (UI) "হ্যাং" হয়ে যেতে পারে, যা একটি খারাপ ব্যবহারকারীর অভিজ্ঞতা তৈরি করে। JavaFX এ এই সমস্যা এড়ানোর জন্য কনকারেন্সি মডেল তৈরি করা হয়েছে যা বিভিন্ন থ্রেডে কাজ করার জন্য একটি সুসংগঠিত উপায় সরবরাহ করে।
JavaFX এর কনকারেন্সি মডেলটি এক্সিকিউশন থ্রেড এবং টাস্কের মধ্যে যোগাযোগের জন্য তিনটি প্রধান উপাদান ব্যবহার করে:
Task
এবং Service
: JavaFX এর মধ্যে Task
এবং Service
ক্লাসগুলি বিশেষভাবে কনকারেন্সি ম্যানেজমেন্টের জন্য ব্যবহৃত হয়।JavaFX UI থ্রেডের পাশাপাশি ব্যাকগ্রাউন্ড থ্রেডে কাজ করতে হলে, আপনাকে সেই থ্রেডে কাজের জন্য Task
বা Service
ব্যবহার করতে হবে। UI থ্রেডে সরাসরি ব্যাকগ্রাউন্ড কাজ করা সম্ভব নয়, তাই এসব ক্লাস UI থ্রেডের থেকে ব্যাকগ্রাউন্ড থ্রেডে কাজ চালানোর সুযোগ দেয় এবং UI-তে পরিবর্তন আনতে সাহায্য করে।
Task
ক্লাস হল একটি Worker
সাবক্লাস যা ব্যাকগ্রাউন্ড কাজের জন্য ব্যবহৃত হয় এবং UI থ্রেডে ফলাফল বা স্ট্যাটাস পাঠানোর জন্য সেট করা যেতে পারে।
Task ক্লাসের সাহায্যে আপনি ব্যাকগ্রাউন্ডে কাজ চালাতে পারেন এবং তার ফলাফল UI থ্রেডে পাঠাতে পারেন।
Service
ক্লাস হল Task
এর একটি উন্নত সংস্করণ, যা পুনরাবৃত্ত কাজ বা লং রানিং টাস্কের জন্য উপযুক্ত। Service
ক্লাসের মধ্যে একটি অতিরিক্ত সুবিধা হল এটি একাধিক থ্রেডে পুনরাবৃত্তি করা যেতে পারে।
নিচে একটি উদাহরণ দেওয়া হয়েছে, যেখানে 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 তে আপডেট হয়।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 তে আপডেট হয়।Task
এবং Service
ক্লাস: এই ক্লাসগুলি পুনরাবৃত্ত কাজ এবং একাধিক টাস্ক ম্যানেজ করতে সাহায্য করে।JavaFX এর Concurrency Model অত্যন্ত শক্তিশালী এবং ইন্টারেক্টিভ অ্যাপ্লিকেশন তৈরি করার জন্য অত্যন্ত গুরুত্বপূর্ণ। এটি UI থ্রেডে কাজ না করে ব্যাকগ্রাউন্ড থ্রেডে লম্বা-running অপারেশন চালানোর সুবিধা দেয় এবং UI কে সহজেই আপডেট করা সম্ভব করে। Task
এবং Service
ক্লাসগুলি আপনার অ্যাপ্লিকেশনের কর্মক্ষমতা বৃদ্ধি করতে সহায়ক।
JavaFX-এর Concurrency Model একটি অত্যন্ত গুরুত্বপূর্ণ বিষয়, যা আপনার অ্যাপ্লিকেশনে ব্যাকগ্রাউন্ড অপারেশন পরিচালনার জন্য ব্যবহৃত হয়। JavaFX-এর ইউজার ইন্টারফেস থ্রেড (UI Thread) মূলত ব্যবহারকারীর ইন্টারঅ্যাকশন পরিচালনা করে, এবং এটি ব্লক হতে দেওয়া উচিত নয়। ব্যাকগ্রাউন্ড অপারেশন সম্পাদন করার জন্য Task এবং Service দুটি গুরুত্বপূর্ণ ক্লাস রয়েছে যা ব্যাকগ্রাউন্ডে কাজ চালাতে সাহায্য করে, এবং UI থ্রেডকে ব্লক না করে কাজ সম্পাদন করা যায়।
Task
হল একটি জেনেরিক ক্লাস যা javafx.concurrent
প্যাকেজের অধীনে আসে। এটি ব্যাকগ্রাউন্ডে একটি কাজ সম্পাদন করার জন্য ব্যবহৃত হয় এবং ইউজার ইন্টারফেসের সাথে ইন্টারঅ্যাকশন করতে update
মেথড ব্যবহার করে।Runnable
ইন্টারফেসের মতো কাজ করে, তবে এটি প্রগ্রেস আপডেট, ফলাফল এবং ব্যর্থতার প্রতিবেদন করার জন্য অতিরিক্ত ফিচার সমর্থন করে।Service
হল একটি আরো উন্নত কনসেপ্ট যা একটি পুনরাবৃত্ত কার্যক্রম (repeated 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()
মেথড ব্যবহার করে প্রগ্রেস পরিবর্তন করবে।ProgressBar
UI উপাদানকে Task
এর প্রগ্রেসের সাথে বাঁধা দেওয়া হয়েছে (progressProperty().bind()
), যাতে প্রগ্রেস বার আপডেট হয়।Task
চালাবে, এবং UI থ্রেড ব্লক হবে না।যখন আপনার একটি পুনরাবৃত্তি কাজ করতে হয় বা একটি দীর্ঘ-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 তৈরি করে |
স্টার্টিং | new Thread(task).start(); | service.start() |
অবস্থা | একবারে একটি কাজ পরিচালনা করে | একাধিক বার চালানো যায় |
Task
একক কাজ পরিচালনা করতে ব্যবহৃত হয়, এবং Service
পুনরাবৃত্তি কাজের জন্য ব্যবহৃত হয়।Platform.runLater()
মেথডটি JavaFX তে ব্যবহৃত হয় যখন আপনি UI থ্রেডে কাজ করতে চান, কিন্তু আপনি অন্য কোন থ্রেড থেকে UI উপাদানগুলির সাথে ইন্টারঅ্যাকশন করছেন। JavaFX অ্যাপ্লিকেশনগুলো single-threaded থাকে এবং UI-র সমস্ত পরিবর্তন JavaFX Application Thread (UI Thread) এ ঘটতে হয়। তবে, আপনি যদি কোনও ব্যাকগ্রাউন্ড থ্রেড (যেমন, একটি নতুন থ্রেড বা Task
ক্লাস) থেকে UI-র কোন উপাদান পরিবর্তন করতে চান, তবে Platform.runLater()
ব্যবহার করতে হবে। এটি নিশ্চিত করে যে UI সংশ্লিষ্ট কাজগুলি UI থ্রেডে সঠিকভাবে সম্পাদিত হবে।
Platform.runLater()
মেথডের কাজ:Platform.runLater()
ব্যবহার করা প্রয়োজন।এই উদাহরণে, ব্যাকগ্রাউন্ড থ্রেড থেকে 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);
}
}
Thread.sleep(2000)
দিয়ে 2 সেকেন্ড বিরতি নিচ্ছে।Platform.runLater()
ব্যবহার করে UI থ্রেডে লেবেলের টেক্সট পরিবর্তন করা হচ্ছে। এতে UI থ্রেডে সঠিকভাবে কাজ হচ্ছে এবং "Text Updated from Background Thread" বার্তা প্রদর্শিত হচ্ছে।এখানে একটি ব্যাকগ্রাউন্ড টাস্কের মাধ্যমে ডেটা প্রসেস করা হচ্ছে এবং সেই ডেটার সাথে 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);
}
}
Platform.runLater()
ব্যবহার করে ব্যাকগ্রাউন্ড থ্রেড থেকে UI-তে প্রগ্রেস আপডেট করা হচ্ছে, যাতে UI থ্রেডে সঠিকভাবে এটি দেখানো যায়।IllegalStateException
হতে পারে।Platform.runLater()
ব্যবহার করা হয়।Platform.runLater()
ব্যবহার করা হয়।Platform.runLater()
ব্যবহার করা হয়।Platform.runLater()
মেথডটি JavaFX অ্যাপ্লিকেশনে ব্যাকগ্রাউন্ড থ্রেড থেকে UI থ্রেডে ইভেন্ট বা কাজ পাঠানোর জন্য ব্যবহৃত হয়।JavaFX Multithreading হল এমন একটি প্রক্রিয়া যার মাধ্যমে একাধিক থ্রেডের সাহায্যে অ্যাপ্লিকেশনটি একাধিক কাজ একসাথে করতে সক্ষম হয়। JavaFX মূলত Single Threaded পরিবেশে কাজ করে, যেখানে সমস্ত UI ইভেন্ট এবং অ্যাকশন একটি একক থ্রেড (JavaFX Application Thread) দ্বারা পরিচালিত হয়। তবে, multithreading ব্যবহার করে আপনি ব্যাকগ্রাউন্ডে কম্পিউটেশন বা দীর্ঘমেয়াদী কাজ চালাতে পারেন, যাতে UI থ্রেডের ওপর কোন চাপ না পড়ে এবং ইউজারের ইন্টারফেস স্ন্যাপি থাকে।
JavaFX অ্যাপ্লিকেশনে Multithreading ব্যবহার করার সময় কিছু সেরা অভ্যাস রয়েছে, যা আপনাকে পারফরম্যান্স উন্নত করতে এবং সঠিকভাবে কাজ করার জন্য সহায়তা করবে।
JavaFX এর UI Thread শুধুমাত্র UI সম্পর্কিত কাজ পরিচালনা করে এবং এটি ব্লক করা যাবে না। আপনি worker thread ব্যবহার করবেন ব্যাকগ্রাউন্ড কাজ করার জন্য এবং এই থ্রেডটি UI থ্রেডের ওপর কোনও প্রভাব ফেলবে না।
Best Practice: ব্যাকগ্রাউন্ড কাজ করার জন্য Task
অথবা Service
ক্লাস ব্যবহার করুন এবং UI-এ তথ্য আপডেট করতে Platform.runLater()
ব্যবহার করুন।
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);
}
}
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!");
});
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);
}
}
অতিরিক্ত দীর্ঘ সময় নেয়া কোনো কাজ UI থ্রেডে সরাসরি না করার চেষ্টা করুন, কারণ এটি অ্যাপ্লিকেশনকে "ফ্রিজ" করতে পারে। সেক্ষেত্রে ব্যাকগ্রাউন্ড থ্রেড ব্যবহার করুন।
Best Practice:
ব্যাকগ্রাউন্ড থ্রেডে যদি কোনো সমস্যা বা exception ঘটে, তবে UI-তে ব্যবহারকারীকে সেটি জানানো প্রয়োজন। JavaFX এর Task
বা Service
ক্লাসে setOnFailed()
ইভেন্ট হ্যান্ডলার ব্যবহার করে এমন exception গুলি হ্যান্ডল করতে পারবেন।
backgroundTask.setOnFailed(event -> {
Throwable exception = backgroundTask.getException();
System.out.println("Error: " + exception.getMessage());
});
কিছু ক্ষেত্রে একাধিক থ্রেড একসাথে চালাতে হতে পারে, যেমন ওয়েব সার্ভিস কল বা মাল্টিপল টাস্ক। এ জন্য ExecutorService
এর মতো থ্রেড পুল ব্যবহার করা যেতে পারে।
ExecutorService executor = Executors.newFixedThreadPool(4);
executor.submit(() -> {
// Perform a background task
});
এই সেরা অভ্যাসগুলো আপনাকে JavaFX অ্যাপ্লিকেশনগুলিতে মাল্টিথ্রেডিং পরিচালনা করতে সাহায্য করবে, যাতে অ্যাপ্লিকেশনটির পারফরম্যান্স উন্নত হয় এবং ইউজারের জন্য স্ন্যাপি ইন্টারফেস নিশ্চিত করা যায়।
Read more