diff --git a/microservices-bulkhead/README.md b/microservices-bulkhead/README.md
new file mode 100644
index 000000000000..be7851c77598
--- /dev/null
+++ b/microservices-bulkhead/README.md
@@ -0,0 +1,192 @@
+---
+title: "Bulkhead Pattern in Java: Isolating Resources for Resilient Microservices"
+shortTitle: Bulkhead
+description: "Learn how the Bulkhead pattern in Java isolates critical system resources to prevent cascade failures in microservices. Includes real-world examples, code demonstrations, and best practices for building resilient distributed systems."
+category: Resilience
+language: en
+tag:
+ - Resilience
+ - Fault tolerance
+ - Microservices
+ - Performance
+ - Scalability
+ - Thread management
+---
+
+## Also known as
+
+* Resource Isolation Pattern
+* Partition Pattern
+
+## Intent of Bulkhead Design Pattern
+
+The Bulkhead pattern isolates critical system resources for each service or component to prevent failures or heavy load in one part of the system from cascading and degrading the entire application. By partitioning resources—often via separate thread pools or connection pools—the system ensures other services remain operational even if one service becomes overloaded or fails.
+
+## Detailed Explanation of Bulkhead Pattern with Real-World Examples
+
+Real-world example
+
+> Consider a modern cruise ship with multiple watertight compartments (bulkheads). If one compartment is breached and starts flooding, the bulkheads prevent water from spreading to other compartments, keeping the ship afloat. Similarly, in software systems, the Bulkhead pattern creates isolated resource pools for different services. If one service experiences issues (like a slow external API or heavy load), it only affects its dedicated resources, while other services continue operating normally with their own resource pools.
+
+In plain words
+
+> The Bulkhead pattern partitions system resources into isolated pools so that failures in one area don't consume all available resources and bring down the entire system.
+
+## Programmatic Example of Bulkhead Pattern in Java
+
+The Bulkhead pattern implementation demonstrates resource isolation using dedicated thread pools for different services. Here we have a `UserService` handling critical user requests and a `BackgroundService` handling non-critical tasks.
+
+First, let's look at the base `BulkheadService` class that provides resource isolation:
+
+```
+public abstract class BulkheadService {
+private static final Logger LOGGER = LoggerFactory.getLogger(BulkheadService.class);
+
+protected final ThreadPoolExecutor executor;
+protected final String serviceName;
+
+protected BulkheadService(String serviceName, int maxPoolSize, int queueCapacity) {
+this.serviceName = serviceName;
+
+ // Create thread pool with bounded queue for resource isolation
+ this.executor = new ThreadPoolExecutor(
+ maxPoolSize,
+ maxPoolSize,
+ 60L,
+ TimeUnit.SECONDS,
+ new ArrayBlockingQueue<>(queueCapacity),
+ new ThreadPoolExecutor.AbortPolicy() // fail-fast when full
+ );
+
+ LOGGER.info("Created {} with {} threads and queue capacity {}",
+ serviceName, maxPoolSize, queueCapacity);
+}
+
+public boolean submitTask(Task task) {
+try {
+executor.execute(() -> processTask(task));
+LOGGER.info("[{}] Task '{}' submitted successfully", serviceName, task.getName());
+return true;
+} catch (RejectedExecutionException e) {
+LOGGER.warn("[{}] Task '{}' REJECTED - bulkhead is full", serviceName, task.getName());
+handleRejectedTask(task);
+return false;
+}
+}
+}
+```
+
+The `UserService` handles critical user-facing requests with dedicated resources:
+
+```
+public class UserService extends BulkheadService {
+private static final int DEFAULT_QUEUE_CAPACITY = 10;
+
+public UserService(int maxThreads) {
+super("UserService", maxThreads, DEFAULT_QUEUE_CAPACITY);
+}
+}
+```
+
+The `BackgroundService` handles non-critical background tasks with its own isolated resources:
+
+```
+public class BackgroundService extends BulkheadService {
+private static final int DEFAULT_QUEUE_CAPACITY = 20;
+
+public BackgroundService(int maxThreads) {
+super("BackgroundService", maxThreads, DEFAULT_QUEUE_CAPACITY);
+}
+}
+```
+
+Here's the demonstration showing how the Bulkhead pattern prevents cascade failures:
+
+```
+public class App {
+public static void main(String[] args) {
+BulkheadService userService = new UserService(3);
+BulkheadService backgroundService = new BackgroundService(2);
+
+ // Overload background service with many tasks
+ for (int i = 1; i <= 10; i++) {
+ Task task = new Task("Heavy-Background-Job-" + i, TaskType.BACKGROUND_PROCESSING, 2000);
+ backgroundService.submitTask(task);
+ }
+
+ // User service remains responsive despite background service overload
+ for (int i = 1; i <= 3; i++) {
+ Task task = new Task("Critical-User-Request-" + i, TaskType.USER_REQUEST, 300);
+ boolean accepted = userService.submitTask(task);
+ LOGGER.info("User request {} accepted: {}", i, accepted);
+ }
+}
+}
+```
+
+Program output:
+
+```
+[BackgroundService] Task 'Heavy-Background-Job-1' submitted successfully
+[BackgroundService] Task 'Heavy-Background-Job-2' submitted successfully
+[BackgroundService] Task 'Heavy-Background-Job-3' REJECTED - bulkhead is full
+...
+[UserService] Task 'Critical-User-Request-1' submitted successfully
+[UserService] Task 'Critical-User-Request-2' submitted successfully
+[UserService] Task 'Critical-User-Request-3' submitted successfully
+User request 1 accepted: true
+User request 2 accepted: true
+User request 3 accepted: true
+```
+
+The output demonstrates that even when the background service is overloaded and rejecting tasks, the user service continues to accept and process requests successfully due to resource isolation.
+
+## When to Use the Bulkhead Pattern in Java
+
+* When building microservices architectures where service failures should not cascade
+* When different operations have varying criticality levels (e.g., user-facing vs. background tasks)
+* When external dependencies (databases, APIs) might become slow or unavailable
+* When you need to guarantee minimum service levels for critical operations
+* In high-throughput systems where resource exhaustion in one area could impact other services
+
+## Real-World Applications of Bulkhead Pattern in Java
+
+* Netflix's Hystrix library implements bulkheads using thread pool isolation
+* Resilience4j provides bulkhead implementations for Java applications
+* AWS Lambda functions run in isolated execution environments (bulkheads)
+* Kubernetes resource limits and quotas implement bulkhead principles
+* Database connection pools per service in microservices architectures
+
+## Benefits and Trade-offs of Bulkhead Pattern
+
+Benefits:
+
+* Prevents cascade failures across services
+* Improves system resilience and availability
+* Provides predictable degradation under load
+* Enables independent scaling of different services
+* Facilitates easier capacity planning and monitoring
+
+Trade-offs:
+
+* Increased resource overhead (multiple thread pools)
+* More complex configuration and tuning
+* Potential for resource underutilization if pools are too large
+* Requires careful capacity planning for each bulkhead
+* May increase overall latency due to queuing
+
+## Related Java Design Patterns
+
+* [Circuit Breaker](https://java-design-patterns.com/patterns/circuit-breaker/): Often used together with Bulkhead; Circuit Breaker stops calling failing services while Bulkhead limits resources
+* [Retry](https://java-design-patterns.com/patterns/retry/): Can be combined with Bulkhead for transient failure handling
+* [Throttling](https://java-design-patterns.com/patterns/throttling/): Similar goal of resource management but focuses on rate limiting rather than isolation
+* [Load Balancer](https://java-design-patterns.com/patterns/load-balancer/): Works at request distribution level while Bulkhead works at resource isolation level
+
+## References and Credits
+
+* [Release It!: Design and Deploy Production-Ready Software](https://amzn.to/3Uul4kF) - Michael T. Nygard
+* [Microservices Patterns: With examples in Java](https://amzn.to/3UyWD5O) - Chris Richardson
+* [Building Microservices: Designing Fine-Grained Systems](https://amzn.to/3RYRz96) - Sam Newman
+* [Resilience4j Documentation - Bulkhead](https://resilience4j.readme.io/docs/bulkhead)
+* [Microsoft Azure Architecture - Bulkhead Pattern](https://learn.microsoft.com/en-us/azure/architecture/patterns/bulkhead)
+* [Microservices.io - Bulkhead Pattern](https://microservices.io/patterns/reliability/bulkhead.html)
\ No newline at end of file
diff --git a/microservices-bulkhead/pom.xml b/microservices-bulkhead/pom.xml
new file mode 100644
index 000000000000..8f5cd2aecfc7
--- /dev/null
+++ b/microservices-bulkhead/pom.xml
@@ -0,0 +1,138 @@
+
+
+
+ 4.0.0
+
+
+ com.iluwatar
+ java-design-patterns
+ 1.26.0-SNAPSHOT
+
+
+ bulkhead
+ jar
+
+ Bulkhead
+
+ The Bulkhead pattern isolates critical system resources for each service or component
+ to prevent failures or heavy load in one part from cascading and degrading the entire system.
+ By partitioning resources via separate thread pools, the system ensures other services
+ remain operational even if one service becomes overloaded or fails.
+
+
+
+ UTF-8
+
+
+
+
+
+ org.slf4j
+ slf4j-api
+
+
+
+
+ ch.qos.logback
+ logback-classic
+ runtime
+
+
+
+
+ org.junit.jupiter
+ junit-jupiter-engine
+ test
+
+
+
+
+ org.junit.jupiter
+ junit-jupiter-params
+ test
+
+
+
+
+ org.mockito
+ mockito-core
+ test
+
+
+
+
+ org.assertj
+ assertj-core
+ 3.27.7
+ test
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+
+
+
+
+ com.diffplug.spotless
+ spotless-maven-plugin
+
+
+
+
+ org.apache.maven.plugins
+ maven-checkstyle-plugin
+
+
+
+
+ org.apache.maven.plugins
+ maven-pmd-plugin
+
+
+
+
+ com.github.spotbugs
+ spotbugs-maven-plugin
+
+
+
+
+
diff --git a/microservices-bulkhead/src/main/java/com/iluwatar/bulkhead/App.java b/microservices-bulkhead/src/main/java/com/iluwatar/bulkhead/App.java
new file mode 100644
index 000000000000..b9b7e207681c
--- /dev/null
+++ b/microservices-bulkhead/src/main/java/com/iluwatar/bulkhead/App.java
@@ -0,0 +1,138 @@
+/*
+ * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK
+ * framework licensed under LGPL (see lgpl-3.0.txt).
+ *
+ * The MIT License Copyright © 2014-2025 Ilkka Seppälä
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+ * and associated documentation files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+ * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+package com.iluwatar.bulkhead;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * The Bulkhead pattern isolates critical system resources for each service or component to prevent
+ * failures or heavy load in one part from cascading and degrading the entire system.
+ *
+ *
In this example, we demonstrate resource isolation using separate thread pools for different
+ * services. The {@link UserService} handles user-facing requests while {@link BackgroundService}
+ * handles background tasks. Each service has its own dedicated thread pool (bulkhead), ensuring
+ * that if one service becomes overloaded, the other continues to function normally.
+ *
+ *
Key concepts demonstrated:
+ *
+ *
+ * - Resource Isolation: Separate thread pools for different services
+ *
- Fail-Fast: Quick rejection when resources are exhausted
+ *
- Resilience: Services remain operational even when others fail
+ *
+ */
+public class App {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(App.class);
+
+ /**
+ * Program entry point.
+ *
+ * @param args command line arguments
+ */
+ public static void main(String[] args) throws InterruptedException {
+ LOGGER.info("Starting Bulkhead Pattern demonstration");
+
+ BulkheadService userService = new UserService(3);
+ BulkheadService backgroundService = new BackgroundService(2);
+
+ try {
+ LOGGER.info("\n=== Scenario 1: Normal Operation ===");
+ demonstrateNormalOperation(userService, backgroundService);
+
+ Thread.sleep(2000);
+
+ LOGGER.info("\n=== Scenario 2: Background Service Overload ===");
+ demonstrateServiceOverload(userService, backgroundService);
+
+ Thread.sleep(3000);
+
+ LOGGER.info("\n=== Scenario 3: Resource Isolation ===");
+ demonstrateResourceIsolation(userService, backgroundService);
+
+ } finally {
+ userService.shutdown();
+ backgroundService.shutdown();
+ LOGGER.info("Bulkhead Pattern demonstration completed");
+ }
+ }
+
+ /**
+ * Demonstrates normal operation where both services handle requests successfully.
+ *
+ * @param userService the user-facing service
+ * @param backgroundService the background processing service
+ */
+ private static void demonstrateNormalOperation(
+ BulkheadService userService, BulkheadService backgroundService) {
+ LOGGER.info("Submitting normal workload to both services");
+ for (int i = 1; i <= 3; i++) {
+ userService.submitTask(new Task("User-Request-" + i, TaskType.USER_REQUEST, 500));
+ }
+ for (int i = 1; i <= 2; i++) {
+ backgroundService.submitTask(
+ new Task("Background-Job-" + i, TaskType.BACKGROUND_PROCESSING, 700));
+ }
+ }
+
+ /**
+ * Demonstrates overloading the background service while user service remains operational. This
+ * shows how the bulkhead pattern prevents cascade failures.
+ *
+ * @param userService the user-facing service
+ * @param backgroundService the background processing service
+ */
+ private static void demonstrateServiceOverload(
+ BulkheadService userService, BulkheadService backgroundService) {
+ LOGGER.info("Overloading background service - user service should remain responsive");
+ for (int i = 1; i <= 10; i++) {
+ backgroundService.submitTask(
+ new Task("Heavy-Background-Job-" + i, TaskType.BACKGROUND_PROCESSING, 2000));
+ }
+ for (int i = 1; i <= 3; i++) {
+ boolean accepted =
+ userService.submitTask(
+ new Task("Critical-User-Request-" + i, TaskType.USER_REQUEST, 300));
+ LOGGER.info("User request {} accepted: {}", i, accepted);
+ }
+ }
+
+ /**
+ * Demonstrates resource isolation by showing independent operation of services.
+ *
+ * @param userService the user-facing service
+ * @param backgroundService the background processing service
+ */
+ private static void demonstrateResourceIsolation(
+ BulkheadService userService, BulkheadService backgroundService) {
+ LOGGER.info("Demonstrating resource isolation between services");
+ LOGGER.info(
+ "User Service - Active threads: {}, Queue size: {}",
+ userService.getActiveThreads(),
+ userService.getQueueSize());
+ LOGGER.info(
+ "Background Service - Active threads: {}, Queue size: {}",
+ backgroundService.getActiveThreads(),
+ backgroundService.getQueueSize());
+ }
+}
diff --git a/microservices-bulkhead/src/main/java/com/iluwatar/bulkhead/BackgroundService.java b/microservices-bulkhead/src/main/java/com/iluwatar/bulkhead/BackgroundService.java
new file mode 100644
index 000000000000..84cdfe32f843
--- /dev/null
+++ b/microservices-bulkhead/src/main/java/com/iluwatar/bulkhead/BackgroundService.java
@@ -0,0 +1,57 @@
+/*
+ * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK
+ * framework licensed under LGPL (see lgpl-3.0.txt).
+ *
+ * The MIT License Copyright © 2014-2025 Ilkka Seppälä
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+ * and associated documentation files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+ * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+package com.iluwatar.bulkhead;
+
+/**
+ * Service for handling background processing tasks with dedicated resources.
+ *
+ * This service handles non-critical, asynchronous operations that can tolerate higher latency.
+ * By isolating its resources from user-facing services, failures or slowdowns in background
+ * processing don't impact critical user operations.
+ *
+ *
Example use cases:
+ *
+ *
+ * - Email sending
+ *
- Report generation
+ *
- Data synchronization
+ *
- Scheduled batch jobs
+ *
+ */
+public class BackgroundService extends BulkheadService {
+
+ private static final int DEFAULT_QUEUE_CAPACITY = 20;
+
+ /**
+ * Creates a BackgroundService with specified thread pool size.
+ *
+ * @param maxThreads maximum number of threads for background processing
+ */
+ public BackgroundService(int maxThreads) {
+ super("BackgroundService", maxThreads, DEFAULT_QUEUE_CAPACITY);
+ }
+
+ @Override
+ protected void handleRejectedTask(Task task) {
+ super.handleRejectedTask(task);
+ }
+}
diff --git a/microservices-bulkhead/src/main/java/com/iluwatar/bulkhead/BulkheadService.java b/microservices-bulkhead/src/main/java/com/iluwatar/bulkhead/BulkheadService.java
new file mode 100644
index 000000000000..4be9aeafacf0
--- /dev/null
+++ b/microservices-bulkhead/src/main/java/com/iluwatar/bulkhead/BulkheadService.java
@@ -0,0 +1,159 @@
+/*
+ * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK
+ * framework licensed under LGPL (see lgpl-3.0.txt).
+ *
+ * The MIT License Copyright © 2014-2025 Ilkka Seppälä
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+ * and associated documentation files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+ * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+package com.iluwatar.bulkhead;
+
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.RejectedExecutionException;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Abstract base class for services implementing the Bulkhead pattern.
+ *
+ * This class provides resource isolation by maintaining a dedicated thread pool for each
+ * service. When the thread pool is exhausted, new tasks are rejected quickly (fail-fast behavior)
+ * rather than blocking or consuming resources from other services.
+ *
+ *
Key features:
+ *
+ *
+ * - Dedicated thread pool with configurable size
+ *
- Bounded queue for pending tasks
+ *
- Fail-fast rejection policy when capacity is reached
+ *
- Metrics for monitoring resource usage
+ *
+ */
+public abstract class BulkheadService {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(BulkheadService.class);
+
+ protected final ThreadPoolExecutor executor;
+ protected final String serviceName;
+
+ /**
+ * Creates a new BulkheadService with specified thread pool configuration.
+ *
+ * @param serviceName name of the service for logging
+ * @param maxPoolSize maximum number of threads in the pool
+ * @param queueCapacity maximum number of tasks that can be queued
+ */
+ protected BulkheadService(String serviceName, int maxPoolSize, int queueCapacity) {
+ this.serviceName = serviceName;
+ this.executor =
+ new ThreadPoolExecutor(
+ maxPoolSize,
+ maxPoolSize,
+ 60L,
+ TimeUnit.SECONDS,
+ new ArrayBlockingQueue<>(queueCapacity),
+ new ThreadPoolExecutor.AbortPolicy());
+ LOGGER.info(
+ "Created {} with {} threads and queue capacity {}",
+ serviceName,
+ maxPoolSize,
+ queueCapacity);
+ }
+
+ /**
+ * Submits a task for execution. Returns false if the task is rejected due to resource exhaustion.
+ *
+ * @param task the task to execute
+ * @return true if task was accepted, false if rejected
+ */
+ public boolean submitTask(Task task) {
+ try {
+ executor.execute(() -> processTask(task));
+ LOGGER.info("[{}] Task '{}' submitted successfully", serviceName, task.getName());
+ return true;
+ } catch (RejectedExecutionException e) {
+ LOGGER.warn(
+ "[{}] Task '{}' REJECTED - bulkhead is full (fail-fast)", serviceName, task.getName());
+ handleRejectedTask(task);
+ return false;
+ }
+ }
+
+ /**
+ * Processes the given task. Subclasses can override for custom behavior.
+ *
+ * @param task the task to process
+ */
+ protected void processTask(Task task) {
+ LOGGER.info(
+ "[{}] Processing task '{}' (type: {}, duration: {}ms)",
+ serviceName,
+ task.getName(),
+ task.getType(),
+ task.getDurationMs());
+ try {
+ Thread.sleep(task.getDurationMs());
+ LOGGER.info("[{}] Task '{}' completed successfully", serviceName, task.getName());
+ } catch (InterruptedException e) {
+ LOGGER.error("[{}] Task '{}' interrupted", serviceName, task.getName());
+ Thread.currentThread().interrupt();
+ }
+ }
+
+ /**
+ * Handles a rejected task. Subclasses can override for custom rejection handling.
+ *
+ * @param task the rejected task
+ */
+ protected void handleRejectedTask(Task task) {
+ LOGGER.info(
+ "[{}] Rejected task '{}' - consider retry or fallback logic", serviceName, task.getName());
+ }
+
+ /**
+ * Gets the number of currently active threads.
+ *
+ * @return number of active threads
+ */
+ public int getActiveThreads() {
+ return executor.getActiveCount();
+ }
+
+ /**
+ * Gets the current queue size.
+ *
+ * @return number of tasks in queue
+ */
+ public int getQueueSize() {
+ return executor.getQueue().size();
+ }
+
+ /** Shuts down the thread pool gracefully. */
+ public void shutdown() {
+ LOGGER.info("[{}] Shutting down thread pool", serviceName);
+ executor.shutdown();
+ try {
+ if (!executor.awaitTermination(5, TimeUnit.SECONDS)) {
+ executor.shutdownNow();
+ }
+ } catch (InterruptedException e) {
+ executor.shutdownNow();
+ Thread.currentThread().interrupt();
+ }
+ }
+}
diff --git a/microservices-bulkhead/src/main/java/com/iluwatar/bulkhead/Task.java b/microservices-bulkhead/src/main/java/com/iluwatar/bulkhead/Task.java
new file mode 100644
index 000000000000..d0a477c49114
--- /dev/null
+++ b/microservices-bulkhead/src/main/java/com/iluwatar/bulkhead/Task.java
@@ -0,0 +1,45 @@
+/*
+ * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK
+ * framework licensed under LGPL (see lgpl-3.0.txt).
+ *
+ * The MIT License Copyright © 2014-2025 Ilkka Seppälä
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+ * and associated documentation files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+ * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+package com.iluwatar.bulkhead;
+
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+
+/**
+ * Represents a task to be executed by a bulkhead service.
+ *
+ * Tasks are characterized by their name, type, and expected duration. This information is useful
+ * for logging, monitoring, and demonstrating the bulkhead pattern's behavior under different loads.
+ */
+@Getter
+@RequiredArgsConstructor
+public class Task {
+
+ private final String name;
+ private final TaskType type;
+ private final long durationMs;
+
+ @Override
+ public String toString() {
+ return "Task{name='" + name + "', type=" + type + ", duration=" + durationMs + "ms}";
+ }
+}
diff --git a/microservices-bulkhead/src/main/java/com/iluwatar/bulkhead/TaskType.java b/microservices-bulkhead/src/main/java/com/iluwatar/bulkhead/TaskType.java
new file mode 100644
index 000000000000..cc9b8a236fae
--- /dev/null
+++ b/microservices-bulkhead/src/main/java/com/iluwatar/bulkhead/TaskType.java
@@ -0,0 +1,36 @@
+/*
+ * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK
+ * framework licensed under LGPL (see lgpl-3.0.txt).
+ *
+ * The MIT License Copyright © 2014-2025 Ilkka Seppälä
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+ * and associated documentation files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+ * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+package com.iluwatar.bulkhead;
+
+/**
+ * Enumeration of task types in the system.
+ *
+ *
Different task types may have different priorities, resource requirements, and SLA
+ * expectations. The bulkhead pattern allows us to isolate resources based on these types.
+ */
+public enum TaskType {
+
+ /** User-facing requests that require low latency and high availability. */
+ USER_REQUEST,
+ /** Background processing tasks that can tolerate higher latency. */
+ BACKGROUND_PROCESSING
+}
diff --git a/microservices-bulkhead/src/main/java/com/iluwatar/bulkhead/UserService.java b/microservices-bulkhead/src/main/java/com/iluwatar/bulkhead/UserService.java
new file mode 100644
index 000000000000..29c32ccace71
--- /dev/null
+++ b/microservices-bulkhead/src/main/java/com/iluwatar/bulkhead/UserService.java
@@ -0,0 +1,56 @@
+/*
+ * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK
+ * framework licensed under LGPL (see lgpl-3.0.txt).
+ *
+ * The MIT License Copyright © 2014-2025 Ilkka Seppälä
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+ * and associated documentation files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+ * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+package com.iluwatar.bulkhead;
+
+/**
+ * Service for handling user-facing requests with dedicated resources.
+ *
+ *
This service represents critical user interactions that require high availability and fast
+ * response times. By isolating its resources using the Bulkhead pattern, it remains responsive even
+ * when other services (like background processing) are experiencing issues or heavy load.
+ *
+ *
Example use cases:
+ *
+ *
+ * - HTTP API requests from users
+ *
- Real-time user interactions
+ *
- Critical business operations
+ *
+ */
+public class UserService extends BulkheadService {
+
+ private static final int DEFAULT_QUEUE_CAPACITY = 10;
+
+ /**
+ * Creates a UserService with specified thread pool size.
+ *
+ * @param maxThreads maximum number of threads for handling user requests
+ */
+ public UserService(int maxThreads) {
+ super("UserService", maxThreads, DEFAULT_QUEUE_CAPACITY);
+ }
+
+ @Override
+ protected void handleRejectedTask(Task task) {
+ super.handleRejectedTask(task);
+ }
+}
diff --git a/microservices-bulkhead/src/test/java/com/iluwatar/bulkhead/AppTest.java b/microservices-bulkhead/src/test/java/com/iluwatar/bulkhead/AppTest.java
new file mode 100644
index 000000000000..f795c7cceb2d
--- /dev/null
+++ b/microservices-bulkhead/src/test/java/com/iluwatar/bulkhead/AppTest.java
@@ -0,0 +1,32 @@
+/*
+ * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK
+ * framework licensed under LGPL (see lgpl-3.0.txt).
+ *
+ * The MIT License Copyright © 2014-2025 Ilkka Seppälä
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+ * and associated documentation files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+ * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+package com.iluwatar.bulkhead;
+
+import org.junit.jupiter.api.Test;
+
+class AppTest {
+
+ @Test
+ void shouldRunWithoutException() throws Exception {
+ App.main(new String[] {});
+ }
+}
diff --git a/microservices-bulkhead/src/test/java/com/iluwatar/bulkhead/BackgroundServiceTest.java b/microservices-bulkhead/src/test/java/com/iluwatar/bulkhead/BackgroundServiceTest.java
new file mode 100644
index 000000000000..81ff54c1bcec
--- /dev/null
+++ b/microservices-bulkhead/src/test/java/com/iluwatar/bulkhead/BackgroundServiceTest.java
@@ -0,0 +1,73 @@
+/*
+ * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK
+ * framework licensed under LGPL (see lgpl-3.0.txt).
+ *
+ * The MIT License Copyright © 2014-2025 Ilkka Seppälä
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+ * and associated documentation files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+ * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+package com.iluwatar.bulkhead;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+class BackgroundServiceTest {
+
+ private BackgroundService backgroundService;
+
+ @BeforeEach
+ void setUp() {
+ backgroundService = new BackgroundService(2);
+ }
+
+ @AfterEach
+ void tearDown() {
+ backgroundService.shutdown();
+ }
+
+ @Test
+ void shouldAcceptBackgroundTask() {
+ assertThat(
+ backgroundService.submitTask(new Task("bg-job-1", TaskType.BACKGROUND_PROCESSING, 0)))
+ .isTrue();
+ }
+
+ @Test
+ void shouldRejectWhenBulkheadIsFull() {
+ for (int i = 0; i < 22; i++) {
+ backgroundService.submitTask(new Task("bg-" + i, TaskType.BACKGROUND_PROCESSING, 5000));
+ }
+ assertThat(
+ backgroundService.submitTask(new Task("overflow", TaskType.BACKGROUND_PROCESSING, 100)))
+ .isFalse();
+ }
+
+ @Test
+ void overloadShouldNotAffectUserService() {
+ var userService = new UserService(2);
+ try {
+ for (int i = 0; i < 25; i++) {
+ backgroundService.submitTask(new Task("bg-" + i, TaskType.BACKGROUND_PROCESSING, 3000));
+ }
+ assertThat(userService.submitTask(new Task("user-req", TaskType.USER_REQUEST, 0))).isTrue();
+ } finally {
+ userService.shutdown();
+ }
+ }
+}
diff --git a/microservices-bulkhead/src/test/java/com/iluwatar/bulkhead/BulkheadServiceTest.java b/microservices-bulkhead/src/test/java/com/iluwatar/bulkhead/BulkheadServiceTest.java
new file mode 100644
index 000000000000..0ff365782ad9
--- /dev/null
+++ b/microservices-bulkhead/src/test/java/com/iluwatar/bulkhead/BulkheadServiceTest.java
@@ -0,0 +1,80 @@
+/*
+ * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK
+ * framework licensed under LGPL (see lgpl-3.0.txt).
+ *
+ * The MIT License Copyright © 2014-2025 Ilkka Seppälä
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+ * and associated documentation files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+ * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+package com.iluwatar.bulkhead;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+class BulkheadServiceTest {
+
+ private UserService service;
+
+ @BeforeEach
+ void setUp() {
+ service = new UserService(2);
+ }
+
+ @AfterEach
+ void tearDown() {
+ service.shutdown();
+ }
+
+ @Test
+ void shouldAcceptTaskWhenCapacityAvailable() {
+ var task = new Task("task-1", TaskType.USER_REQUEST, 0);
+ assertThat(service.submitTask(task)).isTrue();
+ }
+
+ @Test
+ void shouldRejectTaskWhenBulkheadIsFull() {
+ for (int i = 0; i < 12; i++) {
+ service.submitTask(new Task("blocker-" + i, TaskType.USER_REQUEST, 5000));
+ }
+ assertThat(service.submitTask(new Task("overflow", TaskType.USER_REQUEST, 100))).isFalse();
+ }
+
+ @Test
+ void shouldReportActiveThreadCount() throws InterruptedException {
+ service.submitTask(new Task("t1", TaskType.USER_REQUEST, 500));
+ service.submitTask(new Task("t2", TaskType.USER_REQUEST, 500));
+ Thread.sleep(100);
+ assertThat(service.getActiveThreads()).isGreaterThanOrEqualTo(0);
+ }
+
+ @Test
+ void shouldReportQueueSize() throws InterruptedException {
+ service.submitTask(new Task("t1", TaskType.USER_REQUEST, 2000));
+ service.submitTask(new Task("t2", TaskType.USER_REQUEST, 2000));
+ service.submitTask(new Task("queued", TaskType.USER_REQUEST, 2000));
+ Thread.sleep(100);
+ assertThat(service.getQueueSize()).isGreaterThanOrEqualTo(0);
+ }
+
+ @Test
+ void shutdownShouldCompleteWithoutError() {
+ service.submitTask(new Task("t", TaskType.USER_REQUEST, 0));
+ service.shutdown();
+ }
+}
diff --git a/microservices-bulkhead/src/test/java/com/iluwatar/bulkhead/TaskTest.java b/microservices-bulkhead/src/test/java/com/iluwatar/bulkhead/TaskTest.java
new file mode 100644
index 000000000000..8a7238f529e0
--- /dev/null
+++ b/microservices-bulkhead/src/test/java/com/iluwatar/bulkhead/TaskTest.java
@@ -0,0 +1,54 @@
+/*
+ * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK
+ * framework licensed under LGPL (see lgpl-3.0.txt).
+ *
+ * The MIT License Copyright © 2014-2025 Ilkka Seppälä
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+ * and associated documentation files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+ * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+package com.iluwatar.bulkhead;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import org.junit.jupiter.api.Test;
+
+class TaskTest {
+
+ @Test
+ void shouldReturnCorrectName() {
+ var task = new Task("my-task", TaskType.USER_REQUEST, 100);
+ assertThat(task.getName()).isEqualTo("my-task");
+ }
+
+ @Test
+ void shouldReturnCorrectType() {
+ var task = new Task("t", TaskType.BACKGROUND_PROCESSING, 50);
+ assertThat(task.getType()).isEqualTo(TaskType.BACKGROUND_PROCESSING);
+ }
+
+ @Test
+ void shouldReturnCorrectDuration() {
+ var task = new Task("t", TaskType.USER_REQUEST, 250);
+ assertThat(task.getDurationMs()).isEqualTo(250);
+ }
+
+ @Test
+ void toStringShouldContainNameTypeAndDuration() {
+ var task = new Task("my-task", TaskType.USER_REQUEST, 100);
+ var str = task.toString();
+ assertThat(str).contains("my-task").contains("USER_REQUEST").contains("100");
+ }
+}
diff --git a/microservices-bulkhead/src/test/java/com/iluwatar/bulkhead/TaskTypeTest.java b/microservices-bulkhead/src/test/java/com/iluwatar/bulkhead/TaskTypeTest.java
new file mode 100644
index 000000000000..13aaaa70459b
--- /dev/null
+++ b/microservices-bulkhead/src/test/java/com/iluwatar/bulkhead/TaskTypeTest.java
@@ -0,0 +1,44 @@
+/*
+ * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK
+ * framework licensed under LGPL (see lgpl-3.0.txt).
+ *
+ * The MIT License Copyright © 2014-2025 Ilkka Seppälä
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+ * and associated documentation files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+ * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+package com.iluwatar.bulkhead;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import org.junit.jupiter.api.Test;
+
+class TaskTypeTest {
+
+ @Test
+ void shouldHaveTwoValues() {
+ assertThat(TaskType.values()).hasSize(2);
+ }
+
+ @Test
+ void shouldContainUserRequest() {
+ assertThat(TaskType.valueOf("USER_REQUEST")).isEqualTo(TaskType.USER_REQUEST);
+ }
+
+ @Test
+ void shouldContainBackgroundProcessing() {
+ assertThat(TaskType.valueOf("BACKGROUND_PROCESSING")).isEqualTo(TaskType.BACKGROUND_PROCESSING);
+ }
+}
diff --git a/microservices-bulkhead/src/test/java/com/iluwatar/bulkhead/UserServiceTest.java b/microservices-bulkhead/src/test/java/com/iluwatar/bulkhead/UserServiceTest.java
new file mode 100644
index 000000000000..43d7068d1fba
--- /dev/null
+++ b/microservices-bulkhead/src/test/java/com/iluwatar/bulkhead/UserServiceTest.java
@@ -0,0 +1,61 @@
+/*
+ * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK
+ * framework licensed under LGPL (see lgpl-3.0.txt).
+ *
+ * The MIT License Copyright © 2014-2025 Ilkka Seppälä
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+ * and associated documentation files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+ * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+package com.iluwatar.bulkhead;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+class UserServiceTest {
+
+ private UserService userService;
+
+ @BeforeEach
+ void setUp() {
+ userService = new UserService(2);
+ }
+
+ @AfterEach
+ void tearDown() {
+ userService.shutdown();
+ }
+
+ @Test
+ void shouldAcceptUserRequestTask() {
+ assertThat(userService.submitTask(new Task("user-req-1", TaskType.USER_REQUEST, 0))).isTrue();
+ }
+
+ @Test
+ void shouldIsolateFromOverloadedOtherService() {
+ var backgroundService = new BackgroundService(1);
+ try {
+ for (int i = 0; i < 25; i++) {
+ backgroundService.submitTask(new Task("bg-" + i, TaskType.BACKGROUND_PROCESSING, 3000));
+ }
+ assertThat(userService.submitTask(new Task("critical", TaskType.USER_REQUEST, 0))).isTrue();
+ } finally {
+ backgroundService.shutdown();
+ }
+ }
+}
diff --git a/pom.xml b/pom.xml
index 87aa35d6aa1e..9798f36ef09d 100644
--- a/pom.xml
+++ b/pom.xml
@@ -164,6 +164,7 @@
metadata-mapping
microservices-aggregrator
microservices-api-gateway
+ microservices-bulkhead
microservices-client-side-ui-composition
microservices-distributed-tracing
microservices-idempotent-consumer