mirror of
https://github.com/tiennm99/java-design-patterns.git
synced 2026-05-14 06:58:54 +00:00
* Added documentation for Feature Toggle design pattern * Explanation for Feature Toggle Issue #2230 finished, added intent, explanation, programmatic example, applicability and consequences * Finished Explanation for Leader/Followers #2239
This commit is contained in:
@@ -3,28 +3,103 @@ title: Leader/Followers
|
||||
category: Concurrency
|
||||
language: en
|
||||
tag:
|
||||
- Performance
|
||||
- Performance
|
||||
---
|
||||
|
||||
## Intent
|
||||
The Leader/Followers pattern provides a concurrency model where multiple
|
||||
threads can efficiently de-multiplex events and dispatch event handlers
|
||||
that process I/O handles shared by the threads.
|
||||
The Leader/Followers design pattern is a pattern used to coordinate a selection of 'workers'. It allows tasks to execute concurrently
|
||||
with the Leader delegating tasks to the Follower threads for execution. It is a very common design pattern used in multithreaded
|
||||
situations such as servers, and works to help prevent ambiguity around delegation of tasks.
|
||||
|
||||
## Explanation
|
||||
Real-world Example
|
||||
> The best real world example of Leader/Followers is a web server. Web servers have to be able to handle a multitude of incoming
|
||||
> connections all at once. In a web server, the Leader/Followers pattern works by using the Leader to listen to incoming requests
|
||||
> and accept connections. Once a connection is made to a client the Leader can then find a Follower thread to delegate the task
|
||||
> to for execution and return to the client. This means that the Leader does not have to wait to finish execution before it can
|
||||
> accept another incoming connection, and can focus on delegating tasks. This pattern is created to aid in concurrency of applicaitons,
|
||||
> allowing for many connections to work simultaneously.
|
||||
|
||||
In plain words
|
||||
> You can picture the Leader as a traffic controller that has to direct traffic from one lane into 25 lanes. As a car comes in,
|
||||
> the Leader sends it down a road that isn't full or busy. This car can then have its request filled, or reach its destination.
|
||||
> If the Leader had to drive each car down the lane itself, the line would pile up and progress would be slow. But as the Leader
|
||||
> has Followers that can also drive the cars, the Leader can focus on making the line move quickly and ensuring traffic doesn't
|
||||
> back up.
|
||||
|
||||
Wikipedia says
|
||||
> A concurrency pattern are those types of design patterns that deal with the multi-threaded programming paradigm.
|
||||
|
||||
## Programmatic Example
|
||||
This example shows Java code that sets up a Leader that listens for client requests on port 8080. Once a request is sent,
|
||||
the leader will accept it and delegate it to a new Follower to execute. This means that the Leader can keep delegating,
|
||||
and ensure requests are fulfilled timely. This is only pseudocode and the working code would require a more concrete implementation
|
||||
of Leader and Followers.
|
||||
```java
|
||||
public class LeaderFollowerWebServer {
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
int port = 8080; // the port that clients can reach the leader on
|
||||
int numFollowers = 5; // the amount of followers we can delegate tasks to
|
||||
|
||||
ServerSocket serverSocket = new ServerSocket(port); // pseudocode for creating a socket to the server
|
||||
ExecutorService executorService = Executors.newFixedThreadPool(numFollowers); // pseudocode to start execution for Followers
|
||||
|
||||
System.out.println("Web server started. Listening on port " + port);
|
||||
|
||||
while (true) {
|
||||
Socket clientSocket = serverSocket.accept();
|
||||
// Accept a new connection and assign it to a follower thread for processing
|
||||
executorService.execute(new Follower(clientSocket));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Follower implements Runnable {
|
||||
private final Socket clientSocket;
|
||||
|
||||
public Follower(Socket clientSocket) {
|
||||
this.clientSocket = clientSocket;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
// handle the client request, e.g., read and write data
|
||||
// this is where you would implement your request processing logic.
|
||||
// we will just close the socket
|
||||
clientSocket.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
## Class diagram
|
||||

|
||||
|
||||
## Applicability
|
||||
Use Leader-Followers pattern when
|
||||
|
||||
* multiple threads take turns sharing a set of event sources in order to detect, de-multiplex, dispatch and process service requests that occur on the event sources.
|
||||
* You want to establish a concurrent application
|
||||
* You want faster response times on heavy load
|
||||
* You want an easily scalable program
|
||||
* You want to load balance a program
|
||||
|
||||
## Consequences
|
||||
Consequences involved with using the Leader/Followers pattern
|
||||
|
||||
* Implementing this pattern will increase complexity of the code
|
||||
* If the leader is too slow at delegating processes, some Followers may not get to execute tasks leading to a waste of resources
|
||||
* There is overhead with organising and maintaining a thread pool
|
||||
* Debugging is more complex
|
||||
|
||||
## Real world examples
|
||||
|
||||
* [ACE Thread Pool Reactor framework](https://www.dre.vanderbilt.edu/~schmidt/PDF/HPL.pdf)
|
||||
* [JAWS](http://www.dre.vanderbilt.edu/~schmidt/PDF/PDCP.pdf)
|
||||
* [Real-time CORBA](http://www.dre.vanderbilt.edu/~schmidt/PDF/RTS.pdf)
|
||||
* ACE Thread Pool Reactor framework
|
||||
* JAWS
|
||||
* Real-time CORBA
|
||||
|
||||
## Credits
|
||||
|
||||
* [Douglas C. Schmidt and Carlos O’Ryan - Leader/Followers](http://www.kircher-schwanninger.de/michael/publications/lf.pdf)
|
||||
* Douglas C. Schmidt and Carlos O’Ryan - Leader/Followers
|
||||
Reference in New Issue
Block a user