44import org .junit .jupiter .api .Test ;
55import pl .mperor .lab .common .TestUtils ;
66
7- import java .util .Collections ;
8- import java .util .List ;
9- import java .util .NoSuchElementException ;
10- import java .util .SequencedCollection ;
7+ import java .time .Duration ;
8+ import java .util .*;
9+ import java .util .concurrent .ExecutorService ;
10+ import java .util .concurrent .Executors ;
11+ import java .util .stream .IntStream ;
1112
1213/// Java 21™ (September 2023)
1314/// [JDK 21](https://openjdk.org/projects/jdk/21)
@@ -35,6 +36,7 @@ public class Java21 {
3536 @ Test
3637 public void testVirtualThreads () throws InterruptedException {
3738 TestUtils .ReadableOut out = TestUtils .setTempSystemOut ();
39+ // same as Thread.ofVirtual().start(() -> ...)
3840 Thread virtualThread = Thread .startVirtualThread (() ->
3941 System .out .print ("Hello from Virtual Thread!" )
4042 );
@@ -46,13 +48,45 @@ public void testVirtualThreads() throws InterruptedException {
4648 Assertions .assertEquals ("Hello from Virtual Thread!" , out .all ());
4749 }
4850
51+
52+ @ Test
53+ public void testVirtualVsPlatformThreads () {
54+ final int threadPool = 100 ;
55+
56+ long virtualThreadsTime = TestUtils .measureExecutionTimeMillis (() -> {
57+ try (var executor = Executors .newVirtualThreadPerTaskExecutor ()) {
58+ execute (threadPool , executor );
59+ }
60+ }
61+ );
62+
63+ long platformThreadsTime = TestUtils .measureExecutionTimeMillis (() -> {
64+ try (var executor = Executors .newFixedThreadPool (threadPool )) {
65+ execute (threadPool , executor );
66+ }
67+ }
68+ );
69+
70+ System .out .println ("🌀 virtual threads: %s [ms]" .formatted (virtualThreadsTime ));
71+ System .out .println ("🖥️ platform threads: %s [ms]" .formatted (platformThreadsTime ));
72+ Assertions .assertTrue (platformThreadsTime > virtualThreadsTime );
73+ }
74+
75+ private static void execute (int threadPool , ExecutorService executor ) {
76+ IntStream .rangeClosed (0 , threadPool ).forEach (i -> executor .submit (() -> {
77+ Thread .sleep (Duration .ofMillis (100 ));
78+ return i ;
79+ }));
80+ }
81+
4982 @ Test
5083 public void testSequencedCollections () {
5184 List <String > letters = List .of ("one" , "two" , "three" );
52- Assertions .assertInstanceOf (SequencedCollection .class , letters );
5385 Assertions .assertEquals ("one" , letters .getFirst ());
5486 Assertions .assertEquals ("three" , letters .getLast ());
5587 Assertions .assertThrows (NoSuchElementException .class , Collections .emptyList ()::getFirst );
88+ Assertions .assertInstanceOf (SequencedCollection .class , letters );
89+ Assertions .assertInstanceOf (SequencedCollection .class , new LinkedHashMap <>());
5690 }
5791
5892 @ Test
@@ -70,7 +104,8 @@ record LineSegment(Point start, Point end) {}
70104
71105 @ Test
72106 public void testSwitchPatternMatching () {
73- Assertions .assertEquals ("String: Hello" , switchOverClasses ("Hello" ));
107+ Assertions .assertEquals ("Short String: abc" , switchOverClasses ("abc" ));
108+ Assertions .assertEquals ("Long String: longer than abc" , switchOverClasses ("longer than abc" ));
74109 Assertions .assertEquals ("int: 1" , switchOverClasses (1 ));
75110 Assertions .assertEquals ("long: 13" , switchOverClasses (13L ));
76111 Assertions .assertEquals ("boolean: true" , switchOverClasses (true ));
@@ -86,7 +121,8 @@ public String toString() {
86121
87122 private static String switchOverClasses (Object obj ) {
88123 return switch (obj ) {
89- case String s -> String .format ("String: %s" , s );
124+ case String s when s .length () <= 3 -> String .format ("Short String: %s" , s );
125+ case String s -> String .format ("Long String: %s" , s );
90126 case Integer i -> String .format ("int: %d" , i );
91127 case Long l -> String .format ("long: %d" , l );
92128 case Boolean b -> String .format ("boolean: %s" , b );
0 commit comments