mirror of
https://github.com/tiennm99/java-design-patterns.git
synced 2026-10-20 02:17:35 +00:00
deps: Refactor dependencies (#3224)
* remove spring dep move junit, logging, mockito under dep mgmt * upgrade anti-corruption-layer deps * async method invocation * balking, bloc * bridge to bytecode * caching * callback - cqrs * component - health check * hexagonal - metadata mapping * rest of the patterns * remove checkstyle, take spotless into use
This commit is contained in:
1 parent
371439aeaa
commit
0ca162a55c
1863 files changed
+14403
-17632
No files matched your search
@@ -34,10 +34,37 @@
|
||||
</parent>
|
||||
<artifactId>leader-followers</artifactId>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ch.qos.logback</groupId>
|
||||
<artifactId>logback-classic</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-engine</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-assembly-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<configuration>
|
||||
<archive>
|
||||
<manifest>
|
||||
<mainClass>com.iluwatar.leaderfollowers.App</mainClass>
|
||||
</manifest>
|
||||
</archive>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
@@ -39,27 +39,23 @@ import java.util.concurrent.TimeUnit;
|
||||
* work. {@link TaskSet} basically acts as the source of input events for the {@link Worker}, who
|
||||
* are spawned and controlled by the {@link WorkCenter} . When {@link Task} arrives then the leader
|
||||
* takes the work and calls the {@link TaskHandler}. It also calls the {@link WorkCenter} to
|
||||
* promotes one of the followers to be the new leader, who can then process the next work and so
|
||||
* on.
|
||||
* promotes one of the followers to be the new leader, who can then process the next work and so on.
|
||||
*
|
||||
* <p>The pros for this pattern are:
|
||||
* It enhances CPU cache affinity and eliminates unbound allocation and data buffer sharing between
|
||||
* threads by reading the request into buffer space allocated on the stack of the leader or by using
|
||||
* the Thread-Specific Storage pattern [22] to allocate memory. It minimizes locking overhead by not
|
||||
* exchanging data between threads, thereby reducing thread synchronization. In bound handle/thread
|
||||
* associations, the leader thread dispatches the event based on the I/O handle. It can minimize
|
||||
* priority inversion because no extra queuing is introduced in the server. It does not require a
|
||||
* context switch to handle each event, reducing the event dispatching latency. Note that promoting
|
||||
* a follower thread to fulfill the leader role requires a context switch. Programming simplicity:
|
||||
* The Leader/Followers pattern simplifies the programming of concurrency models where multiple
|
||||
* threads can receive requests, process responses, and de-multiplex connections using a shared
|
||||
* handle set.
|
||||
* <p>The pros for this pattern are: It enhances CPU cache affinity and eliminates unbound
|
||||
* allocation and data buffer sharing between threads by reading the request into buffer space
|
||||
* allocated on the stack of the leader or by using the Thread-Specific Storage pattern [22] to
|
||||
* allocate memory. It minimizes locking overhead by not exchanging data between threads, thereby
|
||||
* reducing thread synchronization. In bound handle/thread associations, the leader thread
|
||||
* dispatches the event based on the I/O handle. It can minimize priority inversion because no extra
|
||||
* queuing is introduced in the server. It does not require a context switch to handle each event,
|
||||
* reducing the event dispatching latency. Note that promoting a follower thread to fulfill the
|
||||
* leader role requires a context switch. Programming simplicity: The Leader/Followers pattern
|
||||
* simplifies the programming of concurrency models where multiple threads can receive requests,
|
||||
* process responses, and de-multiplex connections using a shared handle set.
|
||||
*/
|
||||
public class App {
|
||||
|
||||
/**
|
||||
* The main method for the leader followers pattern.
|
||||
*/
|
||||
/** The main method for the leader followers pattern. */
|
||||
public static void main(String[] args) throws InterruptedException {
|
||||
var taskSet = new TaskSet();
|
||||
var taskHandler = new TaskHandler();
|
||||
@@ -68,9 +64,7 @@ public class App {
|
||||
execute(workCenter, taskSet);
|
||||
}
|
||||
|
||||
/**
|
||||
* Start the work, dispatch tasks and stop the thread pool at last.
|
||||
*/
|
||||
/** Start the work, dispatch tasks and stop the thread pool at last. */
|
||||
private static void execute(WorkCenter workCenter, TaskSet taskSet) throws InterruptedException {
|
||||
var workers = workCenter.getWorkers();
|
||||
var exec = Executors.newFixedThreadPool(workers.size());
|
||||
@@ -81,9 +75,7 @@ public class App {
|
||||
exec.shutdownNow();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add tasks.
|
||||
*/
|
||||
/** Add tasks. */
|
||||
private static void addTasks(TaskSet taskSet) throws InterruptedException {
|
||||
var rand = new SecureRandom();
|
||||
for (var i = 0; i < 5; i++) {
|
||||
|
||||
@@ -27,17 +27,12 @@ package com.iluwatar.leaderfollowers;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* A unit of work to be processed by the Workers.
|
||||
*/
|
||||
/** A unit of work to be processed by the Workers. */
|
||||
public class Task {
|
||||
|
||||
@Getter
|
||||
private final int time;
|
||||
@Getter private final int time;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
private boolean finished;
|
||||
@Getter @Setter private boolean finished;
|
||||
|
||||
public Task(int time) {
|
||||
this.time = time;
|
||||
|
||||
@@ -26,15 +26,11 @@ package com.iluwatar.leaderfollowers;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
* The TaskHandler is used by the {@link Worker} to process the newly arrived task.
|
||||
*/
|
||||
/** The TaskHandler is used by the {@link Worker} to process the newly arrived task. */
|
||||
@Slf4j
|
||||
public class TaskHandler {
|
||||
|
||||
/**
|
||||
* This interface handles one task at a time.
|
||||
*/
|
||||
/** This interface handles one task at a time. */
|
||||
public void handleTask(Task task) throws InterruptedException {
|
||||
var time = task.getTime();
|
||||
Thread.sleep(time);
|
||||
|
||||
@@ -27,9 +27,7 @@ package com.iluwatar.leaderfollowers;
|
||||
import java.util.concurrent.ArrayBlockingQueue;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
|
||||
/**
|
||||
* A TaskSet is a collection of the tasks, the leader receives task from here.
|
||||
*/
|
||||
/** A TaskSet is a collection of the tasks, the leader receives task from here. */
|
||||
public class TaskSet {
|
||||
|
||||
private final BlockingQueue<Task> queue = new ArrayBlockingQueue<>(100);
|
||||
|
||||
@@ -35,13 +35,10 @@ import lombok.Getter;
|
||||
*/
|
||||
public class WorkCenter {
|
||||
|
||||
@Getter
|
||||
private Worker leader;
|
||||
@Getter private Worker leader;
|
||||
private final List<Worker> workers = new CopyOnWriteArrayList<>();
|
||||
|
||||
/**
|
||||
* Create workers and set leader.
|
||||
*/
|
||||
/** Create workers and set leader. */
|
||||
public void createWorkers(int numberOfWorkers, TaskSet taskSet, TaskHandler taskHandler) {
|
||||
for (var id = 1; id <= numberOfWorkers; id++) {
|
||||
var worker = new Worker(id, this, taskSet, taskHandler);
|
||||
@@ -58,9 +55,7 @@ public class WorkCenter {
|
||||
workers.remove(worker);
|
||||
}
|
||||
|
||||
/**
|
||||
* Promote a leader.
|
||||
*/
|
||||
/** Promote a leader. */
|
||||
public void promoteLeader() {
|
||||
Worker leader = null;
|
||||
if (!workers.isEmpty()) {
|
||||
|
||||
@@ -27,22 +27,17 @@ package com.iluwatar.leaderfollowers;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
* Worker class that takes work from work center.
|
||||
*/
|
||||
/** Worker class that takes work from work center. */
|
||||
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
|
||||
@Slf4j
|
||||
public class Worker implements Runnable {
|
||||
|
||||
@EqualsAndHashCode.Include
|
||||
private final long id;
|
||||
@EqualsAndHashCode.Include private final long id;
|
||||
private final WorkCenter workCenter;
|
||||
private final TaskSet taskSet;
|
||||
private final TaskHandler taskHandler;
|
||||
|
||||
/**
|
||||
* Constructor to create a worker which will take work from the work center.
|
||||
*/
|
||||
/** Constructor to create a worker which will take work from the work center. */
|
||||
public Worker(long id, WorkCenter workCenter, TaskSet taskSet, TaskHandler taskHandler) {
|
||||
super();
|
||||
this.id = id;
|
||||
@@ -83,5 +78,4 @@ public class Worker implements Runnable {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -28,14 +28,11 @@ import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/**
|
||||
* Application test
|
||||
*/
|
||||
/** Application test */
|
||||
class AppTest {
|
||||
|
||||
@Test
|
||||
void shouldExecuteApplicationWithoutException() {
|
||||
assertDoesNotThrow(() -> App.main(new String[]{}));
|
||||
assertDoesNotThrow(() -> App.main(new String[] {}));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -28,9 +28,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/**
|
||||
* Tests for TaskHandler
|
||||
*/
|
||||
/** Tests for TaskHandler */
|
||||
class TaskHandlerTest {
|
||||
|
||||
@Test
|
||||
@@ -40,5 +38,4 @@ class TaskHandlerTest {
|
||||
taskHandler.handleTask(handle);
|
||||
assertTrue(handle.isFinished());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -28,9 +28,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/**
|
||||
* Tests for TaskSet
|
||||
*/
|
||||
/** Tests for TaskSet */
|
||||
class TaskSetTest {
|
||||
|
||||
@Test
|
||||
@@ -48,5 +46,4 @@ class TaskSetTest {
|
||||
assertEquals(100, task.getTime());
|
||||
assertEquals(0, taskSet.getSize());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -29,9 +29,7 @@ import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/**
|
||||
* Tests for WorkCenter
|
||||
*/
|
||||
/** Tests for WorkCenter */
|
||||
class WorkCenterTest {
|
||||
|
||||
@Test
|
||||
|
||||
Reference in new issue
Block a user