diff --git a/core-java-modules/core-java-perf-2/README.md b/core-java-modules/core-java-perf-2/README.md index 0d8c2d798e..8911c687a0 100644 --- a/core-java-modules/core-java-perf-2/README.md +++ b/core-java-modules/core-java-perf-2/README.md @@ -5,3 +5,4 @@ This module contains articles about performance of Java applications ### Relevant Articles: - [Possible Root Causes for High CPU Usage in Java](https://www.baeldung.com/java-high-cpu-usage-causes) - [External Debugging With JMXTerm](https://www.baeldung.com/java-jmxterm-external-debugging) +- [Create and Detect Memory Leaks in Java](https://www.baeldung.com/java-create-detect-memory-leaks) diff --git a/core-java-modules/core-java-perf-2/pom.xml b/core-java-modules/core-java-perf-2/pom.xml index a9408ca385..a44f6aa8c1 100644 --- a/core-java-modules/core-java-perf-2/pom.xml +++ b/core-java-modules/core-java-perf-2/pom.xml @@ -13,4 +13,11 @@ 0.0.1-SNAPSHOT + + + net.datafaker + datafaker + 1.6.0 + + \ No newline at end of file diff --git a/core-java-modules/core-java-perf-2/src/main/java/com/baeldung/lapsedlistener/LapsedListenerRunner.java b/core-java-modules/core-java-perf-2/src/main/java/com/baeldung/lapsedlistener/LapsedListenerRunner.java new file mode 100644 index 0000000000..50da98e6c4 --- /dev/null +++ b/core-java-modules/core-java-perf-2/src/main/java/com/baeldung/lapsedlistener/LapsedListenerRunner.java @@ -0,0 +1,35 @@ +package com.baeldung.lapsedlistener; + +import static com.baeldung.lapsedlistener.UserGenerator.generateUser; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class LapsedListenerRunner { + + private static final Logger logger = LoggerFactory.getLogger(LapsedListenerRunner.class); + private static final MovieQuoteService movieQuoteService = new MovieQuoteService(); + + static { + movieQuoteService.start(); + } + +public static void main(String[] args) { + while (true) { + User user = generateUser(); + logger.debug("{} logged in", user.getName()); + user.subscribe(movieQuoteService); + userUsingService(); + logger.debug("{} logged out", user.getName()); + } +} + + private static void userUsingService() { + try { + Thread.sleep(10); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + +} diff --git a/core-java-modules/core-java-perf-2/src/main/java/com/baeldung/lapsedlistener/MovieQuoteService.java b/core-java-modules/core-java-perf-2/src/main/java/com/baeldung/lapsedlistener/MovieQuoteService.java new file mode 100644 index 0000000000..95240bbbd5 --- /dev/null +++ b/core-java-modules/core-java-perf-2/src/main/java/com/baeldung/lapsedlistener/MovieQuoteService.java @@ -0,0 +1,47 @@ +package com.baeldung.lapsedlistener; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; +import net.datafaker.Faker; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class MovieQuoteService implements Subject { + + private static final Logger logger = LoggerFactory.getLogger(MovieQuoteService.class); + private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); + private final List observers = new ArrayList<>(); + private final Faker faker = new Faker(); + + @Override + public void attach(Observer observer) { + logger.debug("Current number of subscribed users: {}", observers.size()); + observers.add(observer); + } + + @Override + public void detach(Observer observer) { + observers.remove(observer); + } + + @Override + public void notifyObservers() { + String quote = faker.movie().quote(); + logger.debug("New quote: {}", quote); + for (Observer observer : observers) { + logger.debug("Notifying user: {}", observer); + observer.update(quote); + } + } + + public void start() { + scheduler.scheduleAtFixedRate(this::notifyObservers, 0, 1, TimeUnit.SECONDS); + } + + public int numberOfSubscribers() { + return observers.size(); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-perf-2/src/main/java/com/baeldung/lapsedlistener/Observer.java b/core-java-modules/core-java-perf-2/src/main/java/com/baeldung/lapsedlistener/Observer.java new file mode 100644 index 0000000000..2c4ccf9e06 --- /dev/null +++ b/core-java-modules/core-java-perf-2/src/main/java/com/baeldung/lapsedlistener/Observer.java @@ -0,0 +1,9 @@ +package com.baeldung.lapsedlistener; + +public interface Observer { + void update(String latestNews); + + void subscribe(Subject subject); + + void unsubscribe(Subject subject); +} diff --git a/core-java-modules/core-java-perf-2/src/main/java/com/baeldung/lapsedlistener/Subject.java b/core-java-modules/core-java-perf-2/src/main/java/com/baeldung/lapsedlistener/Subject.java new file mode 100644 index 0000000000..141a7662a7 --- /dev/null +++ b/core-java-modules/core-java-perf-2/src/main/java/com/baeldung/lapsedlistener/Subject.java @@ -0,0 +1,9 @@ +package com.baeldung.lapsedlistener; + +public interface Subject { + void attach(Observer observer); + + void detach(Observer observer); + + void notifyObservers(); +} diff --git a/core-java-modules/core-java-perf-2/src/main/java/com/baeldung/lapsedlistener/User.java b/core-java-modules/core-java-perf-2/src/main/java/com/baeldung/lapsedlistener/User.java new file mode 100644 index 0000000000..0ed0a32a01 --- /dev/null +++ b/core-java-modules/core-java-perf-2/src/main/java/com/baeldung/lapsedlistener/User.java @@ -0,0 +1,70 @@ +package com.baeldung.lapsedlistener; + +public class User implements Observer { + + private final String name; + private final String email; + private final String phone; + private final String street; + private final String city; + private final String state; + private final String zipCode; + + public User(String name, String email, String phone, String street, String city, String state, String zipCode) { + this.name = name; + this.email = email; + this.phone = phone; + this.street = street; + this.city = city; + this.state = state; + this.zipCode = zipCode; + } + + public String getName() { + return name; + } + + public String getEmail() { + return email; + } + + public String getPhone() { + return phone; + } + + public String getStreet() { + return street; + } + + public String getCity() { + return city; + } + + public String getState() { + return state; + } + + public String getZipCode() { + return zipCode; + } + + @Override + public void update(final String quote) { + // user got updated with a new quote + } + + @Override + public void subscribe(final Subject subject) { + subject.attach(this); + } + + @Override + public void unsubscribe(final Subject subject) { + subject.detach(this); + } + + @Override + public String toString() { + return "User [name=" + name + "]"; + } +} diff --git a/core-java-modules/core-java-perf-2/src/main/java/com/baeldung/lapsedlistener/UserGenerator.java b/core-java-modules/core-java-perf-2/src/main/java/com/baeldung/lapsedlistener/UserGenerator.java new file mode 100644 index 0000000000..acdb7d7af7 --- /dev/null +++ b/core-java-modules/core-java-perf-2/src/main/java/com/baeldung/lapsedlistener/UserGenerator.java @@ -0,0 +1,23 @@ +package com.baeldung.lapsedlistener; + +import net.datafaker.Faker; + +public class UserGenerator { + + private UserGenerator() { + } + + private static final Faker faker = new Faker(); + + public static User generateUser() { + String name = faker.name().fullName(); + String email = faker.internet().emailAddress(); + String phone = faker.phoneNumber().cellPhone(); + String street = faker.address().streetAddress(); + String city = faker.address().city(); + String state = faker.address().state(); + String zipCode = faker.address().zipCode(); + return new User(name, email, phone, street, city, state, zipCode); + } + +} \ No newline at end of file diff --git a/core-java-modules/core-java-perf-2/src/test/java/com/baeldung/lapsedlistener/MovieQuoteServiceTest.java b/core-java-modules/core-java-perf-2/src/test/java/com/baeldung/lapsedlistener/MovieQuoteServiceTest.java new file mode 100644 index 0000000000..90c96cba1b --- /dev/null +++ b/core-java-modules/core-java-perf-2/src/test/java/com/baeldung/lapsedlistener/MovieQuoteServiceTest.java @@ -0,0 +1,24 @@ +package com.baeldung.lapsedlistener; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +class MovieQuoteServiceTest { + + @Test + void whenSubscribeToService_thenServiceHasOneSubscriber() { + MovieQuoteService service = new MovieQuoteService(); + service.attach(UserGenerator.generateUser()); + assertEquals(1, service.numberOfSubscribers()); + } + + @Test + void whenUnsubscribeFromService_thenServiceHasNoSubscribers() { + MovieQuoteService service = new MovieQuoteService(); + User user = UserGenerator.generateUser(); + service.attach(user); + service.detach(user); + assertEquals(0, service.numberOfSubscribers()); + } +} \ No newline at end of file