From ee3c6284bf7d464fbe05d0c93a63a8b821a883d9 Mon Sep 17 00:00:00 2001 From: "Michael N. Lipp" Date: Fri, 9 Aug 2024 12:04:10 +0200 Subject: [PATCH] Use virtual threads. --- .../src/org/jgrapes/core/Components.java | 17 ++------- .../org/jgrapes/http/test/ServerTest.java | 5 --- .../org/jgrapes/io/InputStreamMonitor.java | 7 ++-- .../src/org/jgrapes/io/NioDispatcher.java | 4 +-- .../io/util/ManagedBufferStreamer.java | 3 +- .../org/jgrapes/io/util/ThreadCleaner.java | 5 +-- .../src/org/jgrapes/net/SocketServer.java | 6 ++-- .../org/jgrapes/util/FileSystemWatcher.java | 36 +++++++++---------- .../src/org/jgrapes/util/Password.java | 5 +-- 9 files changed, 27 insertions(+), 61 deletions(-) diff --git a/org.jgrapes.core/src/org/jgrapes/core/Components.java b/org.jgrapes.core/src/org/jgrapes/core/Components.java index dea7154625e..2bbb0cdb1f3 100644 --- a/org.jgrapes.core/src/org/jgrapes/core/Components.java +++ b/org.jgrapes.core/src/org/jgrapes/core/Components.java @@ -34,7 +34,6 @@ import java.util.WeakHashMap; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; -import java.util.concurrent.ThreadFactory; import java.util.concurrent.atomic.AtomicLong; import java.util.logging.Level; import org.jgrapes.core.annotation.ComponentManager; @@ -54,17 +53,7 @@ public class Components { private static ExecutorService defaultExecutorService - = Executors.newCachedThreadPool( - new ThreadFactory() { - @SuppressWarnings({ "PMD.CommentRequired", - "PMD.MissingOverride" }) - public Thread newThread(Runnable runnable) { - Thread thread - = Executors.defaultThreadFactory().newThread(runnable); - thread.setDaemon(true); - return thread; - } - }); + = Executors.newVirtualThreadPerTaskExecutor(); private static ExecutorService timerExecutorService = defaultExecutorService; @@ -463,9 +452,7 @@ private static class Scheduler extends Thread { */ @SuppressWarnings("PMD.ConstructorCallsOverridableMethod") public Scheduler() { - setName("Components.Scheduler"); - setDaemon(true); - start(); + ofVirtual().name("Components.Scheduler").start(this); } /** diff --git a/org.jgrapes.http/test/org/jgrapes/http/test/ServerTest.java b/org.jgrapes.http/test/org/jgrapes/http/test/ServerTest.java index e6998b90167..83d3cc3a7e2 100644 --- a/org.jgrapes.http/test/org/jgrapes/http/test/ServerTest.java +++ b/org.jgrapes.http/test/org/jgrapes/http/test/ServerTest.java @@ -208,11 +208,6 @@ public void testConcurrentGetRoot() null, null).toURL(); int threadCount = 1000; - if (Boolean.parseBoolean( - System.getenv().getOrDefault("CI", "false"))) { - threadCount = 100; - } - final List threads = new ArrayList<>(); AtomicInteger pending = new AtomicInteger(0); for (int i = 0; i < threadCount; i++) { diff --git a/org.jgrapes.io/src/org/jgrapes/io/InputStreamMonitor.java b/org.jgrapes.io/src/org/jgrapes/io/InputStreamMonitor.java index 6ef1dcd574d..83446e60b46 100644 --- a/org.jgrapes.io/src/org/jgrapes/io/InputStreamMonitor.java +++ b/org.jgrapes.io/src/org/jgrapes/io/InputStreamMonitor.java @@ -144,11 +144,8 @@ public void onStart(Start event) { () -> { return ByteBuffer.allocateDirect(bufferSize); }, 2); - runner = new Thread(this, Components.simpleObjectName(this)); - // Because this cannot reliably be stopped, it doesn't prevent - // shutdown. - runner.setDaemon(true); - runner.start(); + runner = Thread.ofVirtual().name(Components.simpleObjectName(this)) + .start(this); } } diff --git a/org.jgrapes.io/src/org/jgrapes/io/NioDispatcher.java b/org.jgrapes.io/src/org/jgrapes/io/NioDispatcher.java index e35ab0a484a..374f4a4fad1 100644 --- a/org.jgrapes.io/src/org/jgrapes/io/NioDispatcher.java +++ b/org.jgrapes.io/src/org/jgrapes/io/NioDispatcher.java @@ -63,8 +63,8 @@ public void onStart(Start event) { if (runner != null && !runner.isInterrupted()) { return; } - runner = new Thread(this, Components.simpleObjectName(this)); - runner.start(); + runner = Thread.ofVirtual().name(Components.simpleObjectName(this)) + .start(this); } } diff --git a/org.jgrapes.io/src/org/jgrapes/io/util/ManagedBufferStreamer.java b/org.jgrapes.io/src/org/jgrapes/io/util/ManagedBufferStreamer.java index 59f35f7ec18..9187e05859a 100644 --- a/org.jgrapes.io/src/org/jgrapes/io/util/ManagedBufferStreamer.java +++ b/org.jgrapes.io/src/org/jgrapes/io/util/ManagedBufferStreamer.java @@ -42,10 +42,9 @@ public class ManagedBufferStreamer implements InputConsumer { * @param processor the processor */ public ManagedBufferStreamer(Consumer processor) { - Thread thread = new Thread(() -> { + Thread thread = Thread.ofVirtual().start(() -> { processor.accept(reader); }); - thread.start(); ThreadCleaner.watch(this, thread); } diff --git a/org.jgrapes.io/src/org/jgrapes/io/util/ThreadCleaner.java b/org.jgrapes.io/src/org/jgrapes/io/util/ThreadCleaner.java index be5e3d3903c..11f89da1f47 100644 --- a/org.jgrapes.io/src/org/jgrapes/io/util/ThreadCleaner.java +++ b/org.jgrapes.io/src/org/jgrapes/io/util/ThreadCleaner.java @@ -71,8 +71,7 @@ public RefWithThread(Object referent, Thread thread) { } static { - Thread watchdog = new Thread(() -> { - Thread.currentThread().setName("ThreadCleaner"); + Thread.ofVirtual().name("ThreadCleaner").start(() -> { while (true) { try { ThreadCleaner.RefWithThread ref @@ -84,8 +83,6 @@ public RefWithThread(Object referent, Thread thread) { } } }); - watchdog.setDaemon(true); - watchdog.start(); } /** diff --git a/org.jgrapes.io/src/org/jgrapes/net/SocketServer.java b/org.jgrapes.io/src/org/jgrapes/net/SocketServer.java index a7587b9238b..dd92440e9c3 100644 --- a/org.jgrapes.io/src/org/jgrapes/net/SocketServer.java +++ b/org.jgrapes.io/src/org/jgrapes/net/SocketServer.java @@ -112,7 +112,7 @@ public class SocketServer extends SocketConnectionManager private PermitsPool connLimiter; private Registration registration; @SuppressWarnings("PMD.SingularField") - private Purger purger; + private Thread purger; private long minimumPurgeableTime; /** @@ -127,7 +127,6 @@ private class Purger extends Thread implements AvailabilityListener { */ public Purger() { setName(Components.simpleObjectName(this)); - setDaemon(true); } @Override @@ -418,8 +417,7 @@ public void onRegistered(NioRegistration.Completed event) return; } registration = event.event().get(); - purger = new Purger(); - purger.start(); + purger = Thread.ofVirtual().start(new Purger()); fire(new Ready(serverSocketChannel.getLocalAddress())); return; } diff --git a/org.jgrapes.util/src/org/jgrapes/util/FileSystemWatcher.java b/org.jgrapes.util/src/org/jgrapes/util/FileSystemWatcher.java index a3d3d5663ae..60531c83241 100644 --- a/org.jgrapes.util/src/org/jgrapes/util/FileSystemWatcher.java +++ b/org.jgrapes.util/src/org/jgrapes/util/FileSystemWatcher.java @@ -185,33 +185,29 @@ public DirectorySubscription register(Path toWatch) { */ private final class Watcher { private final WatchService watchService; - private final Thread thread; private Watcher(FileSystem fileSystem) throws IOException { watchService = fileSystem.newWatchService(); - thread = new Thread(() -> { - while (true) { - try { - WatchKey key = watchService.take(); - // Events have to be consumed - key.pollEvents(); - if (!(key.watchable() instanceof Path)) { + Thread.ofVirtual().name(fileSystem.toString() + " watcher") + .start(() -> { + while (true) { + try { + WatchKey key = watchService.take(); + // Events have to be consumed + key.pollEvents(); + if (!(key.watchable() instanceof Path)) { + key.reset(); + continue; + } + handleWatchEvent((Path) key.watchable()); key.reset(); - continue; + } catch (InterruptedException e) { + logger.log(Level.WARNING, e, + () -> "No WatchKey: " + e.getMessage()); } - handleWatchEvent((Path) key.watchable()); - key.reset(); - } catch (InterruptedException e) { - logger.log(Level.WARNING, e, - () -> "No WatchKey: " + e.getMessage()); } - } - }); - thread.setDaemon(true); - thread.setName(fileSystem.toString() + " watcher"); - thread.start(); + }); } - } /** diff --git a/org.jgrapes.util/src/org/jgrapes/util/Password.java b/org.jgrapes.util/src/org/jgrapes/util/Password.java index 69cbe177b87..e9abfcc0961 100644 --- a/org.jgrapes.util/src/org/jgrapes/util/Password.java +++ b/org.jgrapes.util/src/org/jgrapes/util/Password.java @@ -50,7 +50,7 @@ public class Password { public Password(char[] password) { synchronized (Password.class) { if (purger == null) { - purger = new Thread(() -> { + purger = Thread.ofVirtual().name("PasswordPurger").start(() -> { while (true) { try { Reference passwordRef @@ -63,9 +63,6 @@ public Password(char[] password) { } } }); - purger.setName("PasswordPurger"); - purger.setDaemon(true); - purger.start(); } } this.password = password;