-
Notifications
You must be signed in to change notification settings - Fork 70
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add CustomerService with virtual threads and update test classes
Introduced CustomerService using virtual threads for efficient customer data fetching. Renamed existing test and main classes to reflect their use of virtual threads. Added comprehensive test for CustomerService to validate functionality and performance.
- Loading branch information
Showing
5 changed files
with
95 additions
and
3 deletions.
There are no files selected for viewing
46 changes: 46 additions & 0 deletions
46
src/main/java/com/kousenit/virtualthreads/CustomerService.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
package com.kousenit.virtualthreads; | ||
|
||
import java.util.List; | ||
import java.util.concurrent.*; | ||
import java.util.stream.Collectors; | ||
import java.util.stream.IntStream; | ||
|
||
public class CustomerService { | ||
|
||
public List<Customer> fetchCustomerData(List<Integer> customerIds) { | ||
try (ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor()) { | ||
List<CompletableFuture<Customer>> futures = customerIds.stream() | ||
.map(id -> CompletableFuture.supplyAsync(() -> fetchCustomer(id), executor)) | ||
.toList(); | ||
|
||
return CompletableFuture.allOf(futures.toArray(CompletableFuture[]::new)) | ||
.thenApply(v -> futures.stream() | ||
.map(CompletableFuture::join) | ||
.toList()) | ||
.join(); | ||
} | ||
} | ||
|
||
private Customer fetchCustomer(int id) { | ||
try { | ||
// Simulate API call or database query | ||
Thread.sleep(1000); | ||
return new Customer(id, "Customer " + id, "customer" + id + "@example.com"); | ||
} catch (InterruptedException e) { | ||
throw new RuntimeException("Thread interrupted while fetching customer " + id, e); | ||
} | ||
} | ||
|
||
// Customer as a record | ||
public record Customer(int id, String name, String email) {} | ||
|
||
// Main method for demonstration | ||
public static void main(String[] args) { | ||
CustomerService service = new CustomerService(); | ||
List<Integer> customerIds = IntStream.rangeClosed(1, 5) | ||
.boxed() | ||
.collect(Collectors.toList()); | ||
List<Customer> customers = service.fetchCustomerData(customerIds); | ||
customers.forEach(System.out::println); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
46 changes: 46 additions & 0 deletions
46
src/test/java/com/kousenit/virtualthreads/CustomerServiceTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
package com.kousenit.virtualthreads; | ||
|
||
import org.junit.jupiter.api.Test; | ||
|
||
import java.util.List; | ||
import java.util.stream.IntStream; | ||
|
||
import static com.kousenit.virtualthreads.CustomerService.*; | ||
import static org.junit.jupiter.api.Assertions.assertEquals; | ||
import static org.junit.jupiter.api.Assertions.assertTrue; | ||
|
||
class CustomerServiceTest { | ||
|
||
@Test | ||
void testFetchCustomerData() { | ||
CustomerService service = new CustomerService(); | ||
List<Integer> customerIds = IntStream.rangeClosed(1, 500) | ||
.boxed() | ||
.toList(); | ||
|
||
long startTime = System.currentTimeMillis(); | ||
var customers = service.fetchCustomerData(customerIds); | ||
long endTime = System.currentTimeMillis(); | ||
|
||
// Check if we got the correct number of customers | ||
assertEquals(500, customers.size(), "Should fetch 500 customers"); | ||
|
||
// Verify first and last customer data | ||
Customer firstCustomer = customers.getFirst(); | ||
Customer lastCustomer = customers.getLast(); | ||
|
||
assertEquals(1, firstCustomer.id(), "First customer ID should be 1"); | ||
assertEquals("Customer 1", firstCustomer.name(), "First customer name should match"); | ||
assertEquals("[email protected]", firstCustomer.email(), "First customer email should match"); | ||
|
||
assertEquals(500, lastCustomer.id(), "Last customer ID should be 500"); | ||
assertEquals("Customer 500", lastCustomer.name(), "Last customer name should match"); | ||
assertEquals("[email protected]", lastCustomer.email(), "Last customer email should match"); | ||
|
||
// Check if the execution time is close to 1 second (allowing some margin) | ||
long executionTime = endTime - startTime; | ||
assertTrue(executionTime >= 1000 && executionTime < 1500, | ||
"Execution time should be close to 1 second, but was " + executionTime + " ms"); | ||
System.out.println("Execution time: " + executionTime + " ms"); | ||
} | ||
} |