1. import java.util.concurrent.*;
  2. import java.util.concurrent.atomic.AtomicInteger;
  3. public class HtmlMaintenanceQueue {
  4. private final BlockingQueue<String> taskQueue; // Queue for HTML document paths
  5. private final RateLimiter rateLimiter; // Rate limiter for task execution
  6. private final AtomicInteger taskCount = new AtomicInteger(0); //Counter for tasks
  7. public HtmlMaintenanceQueue(int maxRequestsPerSecond) {
  8. this.taskQueue = new LinkedBlockingQueue<>();
  9. this.rateLimiter = new TokenBucketRateLimiter(maxRequestsPerSecond);
  10. }
  11. public synchronized void enqueueTask(String htmlDocumentPath) throws InterruptedException {
  12. // Acquire a token from the rate limiter
  13. rateLimiter.acquire();
  14. // Add the task to the queue
  15. taskQueue.offer(htmlDocumentPath);
  16. System.out.println("Task enqueued: " + htmlDocumentPath);
  17. }
  18. public void processTasks() {
  19. ExecutorService executor = Executors.newFixedThreadPool(1); //Single thread for processing
  20. try {
  21. while (true) {
  22. String htmlDocumentPath = taskQueue.take(); // Get task from the queue
  23. System.out.println("Processing task: " + htmlDocumentPath);
  24. // Simulate maintenance task execution
  25. try {
  26. Thread.sleep(1000); // Simulate processing time
  27. } catch (InterruptedException e) {
  28. Thread.currentThread().interrupt();
  29. }
  30. System.out.println("Task completed: " + htmlDocumentPath);
  31. }
  32. } finally {
  33. executor.shutdown();
  34. }
  35. }
  36. public static void main(String[] args) throws InterruptedException {
  37. int maxRequestsPerSecond = 5; //Limit the rate of requests
  38. HtmlMaintenanceQueue queue = new HtmlMaintenanceQueue(maxRequestsPerSecond);
  39. // Simulate enqueueing tasks
  40. for (int i = 1; i <= 10; i++) {
  41. queue.enqueueTask("html/" + i + ".html");
  42. Thread.sleep(200); //Simulate task arrival rate
  43. }
  44. // Start processing tasks
  45. ExecutorService executor = Executors.newSingleThreadExecutor();
  46. executor.submit(() -> {
  47. queue.processTasks();
  48. });
  49. executor.shutdown();
  50. executor.awaitTermination(10, TimeUnit.SECONDS);
  51. }
  52. //Simple Token Bucket implementation
  53. static class TokenBucketRateLimiter {
  54. private final int capacity;
  55. private final long refillRate;
  56. private long tokens;
  57. private final ScheduledExecutorService refiller;
  58. public TokenBucketRateLimiter(int capacity) {
  59. this.capacity = capacity;
  60. this.tokens = capacity;
  61. this.refiller = Executors.newScheduledThreadPool(1);
  62. refiller.scheduleAtFixedRate(this::refill, 0, 1000, TimeUnit.MILLISECONDS); //Refill every 1 second
  63. }
  64. public synchronized void acquire() throws InterruptedException {
  65. while (tokens <= 0) {
  66. wait(); //Wait until a token is available
  67. }
  68. tokens--;
  69. }
  70. private void refill() {
  71. synchronized (this) {
  72. tokens = Math.min(capacity, tokens + (capacity / 1000)); //Refill at capacity/refillRate
  73. }
  74. }
  75. }
  76. }

Add your comment