Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions Common/src/main/java/pl/mperor/lab/common/TestUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -60,4 +60,11 @@ private E getNext(int index) {
}
}

public static long measureExecutionTimeMillis(Runnable task) {
long startTime = System.currentTimeMillis();
task.run();
long endTime = System.currentTimeMillis();
return endTime - startTime;
}

}
50 changes: 43 additions & 7 deletions JavaReleases/src/test/java/pl/mperor/lab/java/Java21.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@
import org.junit.jupiter.api.Test;
import pl.mperor.lab.common.TestUtils;

import java.util.Collections;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.SequencedCollection;
import java.time.Duration;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.IntStream;

/// Java 21™ (September 2023)
/// [JDK 21](https://openjdk.org/projects/jdk/21)
Expand Down Expand Up @@ -35,6 +36,7 @@ public class Java21 {
@Test
public void testVirtualThreads() throws InterruptedException {
TestUtils.ReadableOut out = TestUtils.setTempSystemOut();
// same as Thread.ofVirtual().start(() -> ...)
Thread virtualThread = Thread.startVirtualThread(() ->
System.out.print("Hello from Virtual Thread!")
);
Expand All @@ -46,13 +48,45 @@ public void testVirtualThreads() throws InterruptedException {
Assertions.assertEquals("Hello from Virtual Thread!", out.all());
}


@Test
public void testVirtualVsPlatformThreads() {
final int threadPool = 100;

long virtualThreadsTime = TestUtils.measureExecutionTimeMillis(() -> {
try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
execute(threadPool, executor);
}
}
);

long platformThreadsTime = TestUtils.measureExecutionTimeMillis(() -> {
try (var executor = Executors.newFixedThreadPool(threadPool)) {
execute(threadPool, executor);
}
}
);

System.out.println("🌀 virtual threads: %s [ms]".formatted(virtualThreadsTime));
System.out.println("🖥️ platform threads: %s [ms]".formatted(platformThreadsTime));
Assertions.assertTrue(platformThreadsTime > virtualThreadsTime);
}

private static void execute(int threadPool, ExecutorService executor) {
IntStream.rangeClosed(0, threadPool).forEach(i -> executor.submit(() -> {
Thread.sleep(Duration.ofMillis(100));
return i;
}));
}

@Test
public void testSequencedCollections() {
List<String> letters = List.of("one", "two", "three");
Assertions.assertInstanceOf(SequencedCollection.class, letters);
Assertions.assertEquals("one", letters.getFirst());
Assertions.assertEquals("three", letters.getLast());
Assertions.assertThrows(NoSuchElementException.class, Collections.emptyList()::getFirst);
Assertions.assertInstanceOf(SequencedCollection.class, letters);
Assertions.assertInstanceOf(SequencedCollection.class, new LinkedHashMap<>().keySet());
}

@Test
Expand All @@ -70,7 +104,8 @@ record LineSegment(Point start, Point end) {}

@Test
public void testSwitchPatternMatching() {
Assertions.assertEquals("String: Hello", switchOverClasses("Hello"));
Assertions.assertEquals("Short String: abc", switchOverClasses("abc"));
Assertions.assertEquals("Long String: longer than abc", switchOverClasses("longer than abc"));
Assertions.assertEquals("int: 1", switchOverClasses(1));
Assertions.assertEquals("long: 13", switchOverClasses(13L));
Assertions.assertEquals("boolean: true", switchOverClasses(true));
Expand All @@ -86,7 +121,8 @@ public String toString() {

private static String switchOverClasses(Object obj) {
return switch (obj) {
case String s -> String.format("String: %s", s);
case String s when s.length() <= 3 -> String.format("Short String: %s", s);
case String s -> String.format("Long String: %s", s);
case Integer i -> String.format("int: %d", i);
case Long l -> String.format("long: %d", l);
case Boolean b -> String.format("boolean: %s", b);
Expand Down
Loading