প্রশ্ন
আপনি কীভাবে জাভা 8 এ একটি যথাযথ পটভূমি লোডার তৈরি করবেন? শর্তসমূহ:
- তথ্য পটভূমিতে লোড করা উচিত
- লোড হওয়ার পরে ডেটা প্রদর্শিত হবে
- ডেটা লোড করার সময় আর কোনও অনুরোধ গ্রহণ করা উচিত নয়
- ডেটা লোড করার সময় যদি অনুরোধগুলি উপস্থিত থাকে তবে নির্দিষ্ট সময়সীমা (উদাহরণস্বরূপ 5 সেকেন্ড) পরে আরেকটি লোডিং নির্ধারিত করা উচিত
উদ্দেশ্য হল উদাহরণস্বরূপ পুনরায় লোড অনুরোধগুলি গ্রহণ করা হয়, তবে অনুরোধগুলি দিয়ে ডাটাবেস প্লাবিত হয় না।
MCVE
এখানে একটি এমসিভিই আছে। এটি একটি ব্যাকগ্রাউন্ড টাস্ক নিয়ে গঠিত যা কেবলমাত্র থ্রেডকে অনুরোধ করে লোডিংকে সিমুলেট করে 2 সেকেন্ডের জন্য ঘুমান। টাস্কটি প্রতি সেকেন্ডে নির্ধারিত হয় যা প্রাকৃতিকভাবে পটভূমি লোডিং কাজের একটি ওভারল্যাপের দিকে নিয়ে যায়, যা এড়ানো উচিত।
public class LoadInBackgroundExample {
/**
* A simple background task which should perform the data loading operation. In this minimal example it simply invokes Thread.sleep
*/
public static class BackgroundTask implements Runnable {
private int id;
public BackgroundTask(int id) {
this.id = id;
}
/**
* Sleep for a given amount of time to simulate loading.
*/
@Override
public void run() {
try {
System.out.println("Start #" + id + ": " + Thread.currentThread());
long sleepTime = 2000;
Thread.sleep( sleepTime);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
System.out.println("Finish #" + id + ": " + Thread.currentThread());
}
}
}
/**
* CompletableFuture which simulates loading and showing data.
* @param taskId Identifier of the current task
*/
public static void loadInBackground( int taskId) {
// create the loading task
BackgroundTask backgroundTask = new BackgroundTask( taskId);
// "load" the data asynchronously
CompletableFuture<String> completableFuture = CompletableFuture.supplyAsync(new Supplier<String>() {
@Override
public String get() {
CompletableFuture<Void> future = CompletableFuture.runAsync(backgroundTask);
try {
future.get();
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
return "task " + backgroundTask.id;
}
});
// display the data after they are loaded
CompletableFuture<Void> future = completableFuture.thenAccept(x -> {
System.out.println( "Background task finished:" + x);
});
}
public static void main(String[] args) {
// runnable which invokes the background loader every second
Runnable trigger = new Runnable() {
int taskId = 0;
public void run() {
loadInBackground( taskId++);
}
};
// create scheduler
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
ScheduledFuture<?> beeperHandle = scheduler.scheduleAtFixedRate(trigger, 0, 1, TimeUnit.SECONDS);
// cancel the scheudler and the application after 10 seconds
scheduler.schedule(() -> beeperHandle.cancel(true), 10, TimeUnit.SECONDS);
try {
beeperHandle.get();
} catch (Throwable th) {
}
System.out.println( "Cancelled");
System.exit(0);
}
}
আউটপুটটি হ'ল:
Start #0: Thread[ForkJoinPool.commonPool-worker-2,5,main]
Start #1: Thread[ForkJoinPool.commonPool-worker-4,5,main]
Start #2: Thread[ForkJoinPool.commonPool-worker-6,5,main]
Finish #0: Thread[ForkJoinPool.commonPool-worker-2,5,main]
Background task finished:task 0
Finish #1: Thread[ForkJoinPool.commonPool-worker-4,5,main]
Background task finished:task 1
Start #3: Thread[ForkJoinPool.commonPool-worker-4,5,main]
Finish #2: Thread[ForkJoinPool.commonPool-worker-6,5,main]
Background task finished:task 2
Start #4: Thread[ForkJoinPool.commonPool-worker-6,5,main]
Start #5: Thread[ForkJoinPool.commonPool-worker-2,5,main]
Finish #3: Thread[ForkJoinPool.commonPool-worker-4,5,main]
Background task finished:task 3
Start #6: Thread[ForkJoinPool.commonPool-worker-4,5,main]
Finish #4: Thread[ForkJoinPool.commonPool-worker-6,5,main]
Background task finished:task 4
Finish #5: Thread[ForkJoinPool.commonPool-worker-2,5,main]
Background task finished:task 5
Start #7: Thread[ForkJoinPool.commonPool-worker-2,5,main]
Finish #6: Thread[ForkJoinPool.commonPool-worker-4,5,main]
Start #8: Thread[ForkJoinPool.commonPool-worker-6,5,main]
Background task finished:task 6
Start #9: Thread[ForkJoinPool.commonPool-worker-4,5,main]
Finish #7: Thread[ForkJoinPool.commonPool-worker-2,5,main]
Background task finished:task 7
Start #10: Thread[ForkJoinPool.commonPool-worker-2,5,main]
Finish #8: Thread[ForkJoinPool.commonPool-worker-6,5,main]
Background task finished:task 8
Cancelled
লক্ষ্যটি হ'ল উদাঃ # 1 এবং # 2 এড়িয়ে গেছেন কারণ # 0 এখনও চলছে।
সমস্যা
আপনি ব্লকিং প্রক্রিয়াটি সঠিকভাবে কোথায় সেট করবেন? সিঙ্ক্রোনাইজেশন ব্যবহার করা উচিত? নাকি কিছু AtomicBoolean? এবং যদি তা হয়, তবে এটি get()পদ্ধতির ভিতরে বা অন্য কোথাও হওয়া উচিত ?
ExecutorServiceথ্রেড পুল আকারের 1 এর সাথে বিবেচনা করেছেন?
BlockingQueue?