diff --git a/src/hotspot/share/jfr/support/jfrIntrinsics.hpp b/src/hotspot/share/jfr/support/jfrIntrinsics.hpp
index 6520f3cb00ca0..77affc69926f0 100644
--- a/src/hotspot/share/jfr/support/jfrIntrinsics.hpp
+++ b/src/hotspot/share/jfr/support/jfrIntrinsics.hpp
@@ -47,7 +47,7 @@ class JfrIntrinsicSupport : AllStatic {
 #define JFR_HAVE_INTRINSICS
 
 #define JFR_TEMPLATES(template)                                                                                      \
-  template(jdk_jfr_internal_HiddenWait,                               "jdk/jfr/internal/HiddenWait")                 \
+  template(jdk_jfr_internal_management_HiddenWait,                    "jdk/jfr/internal/management/HiddenWait")      \
   template(jdk_jfr_internal_JVM,                                      "jdk/jfr/internal/JVM")                        \
   template(jdk_jfr_internal_event_EventWriterFactory,                 "jdk/jfr/internal/event/EventWriterFactory")   \
   template(jdk_jfr_internal_event_EventConfiguration_signature,       "Ljdk/jfr/internal/event/EventConfiguration;") \
diff --git a/src/hotspot/share/runtime/objectMonitor.cpp b/src/hotspot/share/runtime/objectMonitor.cpp
index ba463231592c5..c509ed691cdb8 100644
--- a/src/hotspot/share/runtime/objectMonitor.cpp
+++ b/src/hotspot/share/runtime/objectMonitor.cpp
@@ -1442,7 +1442,7 @@ bool ObjectMonitor::check_owner(TRAPS) {
 static inline bool is_excluded(const Klass* monitor_klass) {
   assert(monitor_klass != nullptr, "invariant");
   NOT_JFR_RETURN_(false);
-  JFR_ONLY(return vmSymbols::jdk_jfr_internal_HiddenWait() == monitor_klass->name();)
+  JFR_ONLY(return vmSymbols::jdk_jfr_internal_management_HiddenWait() == monitor_klass->name();)
 }
 
 static void post_monitor_wait_event(EventJavaMonitorWait* event,
diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/JVM.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/JVM.java
index 2e600c8c02974..cc0ee05a948a5 100644
--- a/src/jdk.jfr/share/classes/jdk/jfr/internal/JVM.java
+++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/JVM.java
@@ -31,6 +31,7 @@
 import jdk.jfr.Event;
 import jdk.jfr.internal.event.EventConfiguration;
 import jdk.jfr.internal.event.EventWriter;
+import jdk.jfr.internal.management.HiddenWait;
 
 /**
  * Interface against the JVM.
diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/JVMSupport.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/JVMSupport.java
index 114052ecea250..7fde28a3d21fc 100644
--- a/src/jdk.jfr/share/classes/jdk/jfr/internal/JVMSupport.java
+++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/JVMSupport.java
@@ -30,6 +30,7 @@
 
 import jdk.jfr.Recording;
 import jdk.jfr.internal.event.EventConfiguration;
+import jdk.jfr.internal.management.HiddenWait;
 import jdk.jfr.internal.util.Utils;
 import jdk.jfr.internal.util.ValueFormatter;
 
@@ -118,7 +119,8 @@ private static void awaitUniqueTimestamp() {
                 lastTimestamp = time;
                 return;
             }
-            Utils.takeNap(1);
+            HiddenWait hiddenWait = new HiddenWait();
+            hiddenWait.takeNap(1);
         }
     }
 
diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/MetadataRepository.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/MetadataRepository.java
index 75be70a0d1dae..1ddae489917b6 100644
--- a/src/jdk.jfr/share/classes/jdk/jfr/internal/MetadataRepository.java
+++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/MetadataRepository.java
@@ -49,6 +49,7 @@
 import jdk.jfr.ValueDescriptor;
 import jdk.jfr.internal.consumer.RepositoryFiles;
 import jdk.jfr.internal.event.EventConfiguration;
+import jdk.jfr.internal.management.HiddenWait;
 import jdk.jfr.internal.periodic.PeriodicEvents;
 import jdk.jfr.internal.util.Utils;
 
@@ -59,6 +60,7 @@ public final class MetadataRepository {
     private final Map<String, EventType> nativeEventTypes = LinkedHashMap.newHashMap(150);
     private final Map<String, EventControl> nativeControls = LinkedHashMap.newHashMap(150);
     private final SettingsManager settingsManager = new SettingsManager();
+    private final HiddenWait threadSleeper = new HiddenWait();
     private Constructor<EventConfiguration> cachedEventConfigurationConstructor;
     private boolean staleMetadata = true;
     private boolean unregistered;
@@ -343,7 +345,7 @@ private void awaitEpochMilliShift() {
                 lastMillis = millis;
                 return;
             }
-            Utils.takeNap(1);
+            threadSleeper.takeNap(1);
         }
     }
 
diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/consumer/OngoingStream.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/consumer/OngoingStream.java
index 1816d00f345a7..e0dd7fa2ad8d5 100644
--- a/src/jdk.jfr/share/classes/jdk/jfr/internal/consumer/OngoingStream.java
+++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/consumer/OngoingStream.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -33,6 +33,7 @@
 import jdk.jfr.internal.SecuritySupport;
 import jdk.jfr.internal.SecuritySupport.SafePath;
 import jdk.jfr.internal.management.EventByteStream;
+import jdk.jfr.internal.management.HiddenWait;
 import jdk.jfr.internal.management.ManagementSupport;
 
 public final class OngoingStream extends EventByteStream {
@@ -44,6 +45,7 @@ public final class OngoingStream extends EventByteStream {
 
     private final RepositoryFiles repositoryFiles;
     private final Recording recording;
+    private final HiddenWait threadSleeper = new HiddenWait();
     private final int blockSize;
     private final long endTimeNanos;
     private final byte[] headerBytes = new byte[HEADER_SIZE];
@@ -195,19 +197,13 @@ private byte[] readWithHeader(int size) throws IOException {
                     return bytes;
                 }
             }
-            takeNap();
+            if (!threadSleeper.takeNap(10)) {
+                throw new IOException("Read operation interrupted");
+            }
         }
         return EMPTY_ARRAY;
     }
 
-    private void takeNap() throws IOException {
-        try {
-            Thread.sleep(10);
-        } catch (InterruptedException ie) {
-            throw new IOException("Read operation interrupted", ie);
-        }
-    }
-
     private boolean ensureInput() throws IOException {
         if (input == null) {
             if (SecuritySupport.getFileSize(new SafePath(path)) < HEADER_SIZE) {
diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/consumer/RecordingInput.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/consumer/RecordingInput.java
index 90a03130f4990..69ec73f57fd6f 100644
--- a/src/jdk.jfr/share/classes/jdk/jfr/internal/consumer/RecordingInput.java
+++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/consumer/RecordingInput.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -31,6 +31,8 @@
 import java.io.IOException;
 import java.io.RandomAccessFile;
 import java.nio.file.Path;
+
+import jdk.jfr.internal.management.HiddenWait;
 import jdk.jfr.internal.util.Utils;
 
 public final class RecordingInput implements DataInput, AutoCloseable {
@@ -67,6 +69,7 @@ public void reset() {
     }
     private final int blockSize;
     private final FileAccess fileAccess;
+    private final HiddenWait threadSleeper = new HiddenWait();
     private long pollCount = 1000;
     private RandomAccessFile file;
     private String filename;
@@ -453,6 +456,6 @@ public void pollWait() throws IOException {
         if (pollCount < 0) {
             throw new IOException("Recording file is stuck in locked stream state.");
         }
-        Utils.takeNap(1);
+        threadSleeper.takeNap(1);
     }
 }
diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/consumer/RepositoryFiles.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/consumer/RepositoryFiles.java
index 6ef88ecad3750..3f0611f998173 100644
--- a/src/jdk.jfr/share/classes/jdk/jfr/internal/consumer/RepositoryFiles.java
+++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/consumer/RepositoryFiles.java
@@ -46,9 +46,10 @@
 import jdk.jfr.internal.Logger;
 import jdk.jfr.internal.Repository;
 import jdk.jfr.internal.SecuritySupport.SafePath;
+import jdk.jfr.internal.management.HiddenWait;;
 
 public final class RepositoryFiles {
-    private static final Object WAIT_OBJECT = new Object();
+    private static final HiddenWait WAIT_OBJECT = new HiddenWait();
     private static final String DIRECTORY_PATTERN = "DDDD_DD_DD_DD_DD_DD_";
     public static void notifyNewFile() {
         synchronized (WAIT_OBJECT) {
@@ -59,7 +60,7 @@ public static void notifyNewFile() {
     private final FileAccess fileAccess;
     private final NavigableMap<Long, Path> pathSet = new TreeMap<>();
     private final Map<Path, Long> pathLookup = new HashMap<>();
-    private final Object waitObject;
+    private final HiddenWait waitObject;
     private boolean allowSubDirectory;
     private volatile boolean closed;
     private Path repository;
@@ -67,7 +68,7 @@ public static void notifyNewFile() {
     public RepositoryFiles(FileAccess fileAccess, Path repository, boolean allowSubDirectory) {
         this.repository = repository;
         this.fileAccess = fileAccess;
-        this.waitObject = repository == null ? WAIT_OBJECT : new Object();
+        this.waitObject = repository == null ? WAIT_OBJECT : new HiddenWait();
         this.allowSubDirectory = allowSubDirectory;
     }
 
@@ -108,7 +109,7 @@ private boolean updatePaths(boolean wait) {
                 // was accessed. Just ignore, and retry later.
             }
             if (wait) {
-                nap();
+                waitObject.takeNap(1000);
             } else {
                 return pathLookup.size() > beforeSize;
             }
@@ -157,16 +158,6 @@ private Path path(long timestamp, boolean wait) {
         }
     }
 
-    private void nap() {
-        try {
-            synchronized (waitObject) {
-                waitObject.wait(1000);
-            }
-        } catch (InterruptedException e) {
-            // ignore
-        }
-    }
-
     private boolean updatePaths() throws IOException, DirectoryIteratorException {
         boolean foundNew = false;
         Path repoPath = repository;
diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/HiddenWait.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/management/HiddenWait.java
similarity index 82%
rename from src/jdk.jfr/share/classes/jdk/jfr/internal/HiddenWait.java
rename to src/jdk.jfr/share/classes/jdk/jfr/internal/management/HiddenWait.java
index 26505990332c9..9070faad5a658 100644
--- a/src/jdk.jfr/share/classes/jdk/jfr/internal/HiddenWait.java
+++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/management/HiddenWait.java
@@ -22,11 +22,21 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-package jdk.jfr.internal;
+package jdk.jfr.internal.management;
 
 /**
  * The HiddenWait class is used to exclude jdk.JavaMonitorWait events
  * from being generated when Object.wait() is called on an object of this type.
  */
 public final class HiddenWait {
+
+    public synchronized boolean takeNap(long timeoutMillis) {
+        try {
+            this.wait(timeoutMillis);
+            return true;
+        } catch (InterruptedException e) {
+            // Ok, ignore
+            return false;
+        }
+    }
 }
diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/management/StreamBarrier.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/management/StreamBarrier.java
index 0b3132da2178b..7f1db163b4e3d 100644
--- a/src/jdk.jfr/share/classes/jdk/jfr/internal/management/StreamBarrier.java
+++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/management/StreamBarrier.java
@@ -39,45 +39,57 @@
  * processing should not continue.
  */
 public final class StreamBarrier implements Closeable {
-
+    private final HiddenWait lock = new HiddenWait();
     private boolean activated = false;
     private boolean used = false;
     private long end = Long.MAX_VALUE;
 
     // Blocks thread until barrier is deactivated
-    public synchronized void check() {
-        while (activated) {
-            try {
-                this.wait();
-            } catch (InterruptedException e) {
-                Thread.currentThread().interrupt();
+    public void check() {
+        synchronized (lock) {
+            while (activated) {
+                try {
+                    lock.wait();
+                } catch (InterruptedException e) {
+                    Thread.currentThread().interrupt();
+                }
             }
         }
     }
 
-    public synchronized void setStreamEnd(long timestamp) {
-        end = timestamp;
+    public void setStreamEnd(long timestamp) {
+        synchronized(lock) {
+            end = timestamp;
+        }
     }
 
-    public synchronized long getStreamEnd() {
-        return end;
+    public long getStreamEnd() {
+        synchronized(lock) {
+            return end;
+        }
     }
 
-    public synchronized void activate() {
-        activated = true;
-        used = true;
+    public void activate() {
+        synchronized (lock) {
+            activated = true;
+            used = true;
+        }
     }
 
     @Override
     public synchronized void close() throws IOException {
-        activated = false;
-        this.notifyAll();
+        synchronized (lock) {
+            activated = false;
+            lock.notifyAll();
+        }
     }
 
     /**
      * Returns {@code true) if barrier is, or has been, in active state, {@code false) otherwise.
      */
-    public synchronized boolean used() {
-        return used;
+    public boolean used() {
+        synchronized (lock) {
+            return used;
+        }
     }
 }
diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/util/Utils.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/util/Utils.java
index 5e04a25fe7ddf..ae83727096a2a 100644
--- a/src/jdk.jfr/share/classes/jdk/jfr/internal/util/Utils.java
+++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/util/Utils.java
@@ -48,19 +48,19 @@
 import jdk.jfr.Event;
 import jdk.jfr.EventType;
 import jdk.jfr.RecordingState;
-import jdk.jfr.internal.HiddenWait;
 import jdk.jfr.internal.LogLevel;
 import jdk.jfr.internal.LogTag;
 import jdk.jfr.internal.Logger;
 import jdk.jfr.internal.MirrorEvent;
 import jdk.jfr.internal.SecuritySupport;
 import jdk.jfr.internal.Type;
+import jdk.jfr.internal.management.HiddenWait;
 import jdk.jfr.internal.settings.PeriodSetting;
 import jdk.jfr.internal.settings.StackTraceSetting;
 import jdk.jfr.internal.settings.ThresholdSetting;
 
 public final class Utils {
-    private static final Object flushObject = new Object();
+    private static final HiddenWait flushObject = new HiddenWait();
     private static final String LEGACY_EVENT_NAME_PREFIX = "com.oracle.jdk.";
 
     /**
@@ -351,17 +351,6 @@ private static boolean isSupportedType(Class<?> type) {
         return Type.isValidJavaFieldType(type.getName());
     }
 
-    public static void takeNap(long millis) {
-        HiddenWait hiddenWait = new HiddenWait();
-        try {
-            synchronized(hiddenWait) {
-                hiddenWait.wait(millis);
-            }
-        } catch (InterruptedException e) {
-            // ok
-        }
-    }
-
     public static void notifyFlush() {
         synchronized (flushObject) {
             flushObject.notifyAll();
@@ -369,13 +358,7 @@ public static void notifyFlush() {
     }
 
     public static void waitFlush(long timeOut) {
-        synchronized (flushObject) {
-            try {
-                flushObject.wait(timeOut);
-            } catch (InterruptedException e) {
-                // OK
-            }
-        }
+        flushObject.takeNap(timeOut);
     }
 
     public static Instant epochNanosToInstant(long epochNanos) {
diff --git a/src/jdk.management.jfr/share/classes/jdk/management/jfr/DownLoadThread.java b/src/jdk.management.jfr/share/classes/jdk/management/jfr/DownLoadThread.java
index 5ce66692537cb..05895f0f4a99b 100644
--- a/src/jdk.management.jfr/share/classes/jdk/management/jfr/DownLoadThread.java
+++ b/src/jdk.management.jfr/share/classes/jdk/management/jfr/DownLoadThread.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -30,12 +30,14 @@
 import java.util.Map;
 
 import jdk.jfr.internal.management.ManagementSupport;
+import jdk.jfr.internal.management.HiddenWait;
 
 final class DownLoadThread extends Thread {
     private final RemoteRecordingStream stream;
     private final Instant startTime;
     private final Instant endTime;
     private final DiskRepository diskRepository;
+    private final HiddenWait threadSleeper = new HiddenWait();
 
     DownLoadThread(RemoteRecordingStream stream, String name) {
         super(name);
@@ -64,7 +66,7 @@ public void run() {
                 if (bytes.length != 0) {
                     diskRepository.write(bytes);
                 } else {
-                    takeNap();
+                    threadSleeper.takeNap(1000);
                 }
             }
         } catch (IOException ioe) {
@@ -73,12 +75,4 @@ public void run() {
            diskRepository.complete();
         }
     }
-
-    private void takeNap() {
-        try {
-            Thread.sleep(1000);
-        } catch (InterruptedException ie) {
-            // ignore
-        }
-    }
 }
diff --git a/src/jdk.management.jfr/share/classes/jdk/management/jfr/FileDump.java b/src/jdk.management.jfr/share/classes/jdk/management/jfr/FileDump.java
index 7da0fe351c450..37ba296732635 100644
--- a/src/jdk.management.jfr/share/classes/jdk/management/jfr/FileDump.java
+++ b/src/jdk.management.jfr/share/classes/jdk/management/jfr/FileDump.java
@@ -32,8 +32,10 @@
 import java.util.Deque;
 
 import jdk.management.jfr.DiskRepository.DiskChunk;
+import jdk.jfr.internal.management.HiddenWait;
 
 final class FileDump {
+    private final HiddenWait lock = new HiddenWait();
     private final Deque<DiskChunk> chunks = new ArrayDeque<>();
     private final long stopTimeMillis;
     private boolean complete;
@@ -42,45 +44,53 @@ final class FileDump {
         this.stopTimeMillis = stopTimeMillis;
     }
 
-    public synchronized void add(DiskChunk dc) {
-        if (isComplete()) {
-            return;
-        }
-        dc.acquire();
-        chunks.addFirst(dc);
-        long endMillis = dc.endTimeNanos / 1_000_000;
-        if (endMillis >= stopTimeMillis) {
-            setComplete();
+    public void add(DiskChunk dc) {
+        synchronized (lock) {
+            if (isComplete()) {
+                return;
+            }
+            dc.acquire();
+            chunks.addFirst(dc);
+            long endMillis = dc.endTimeNanos / 1_000_000;
+            if (endMillis >= stopTimeMillis) {
+                setComplete();
+            }
         }
     }
 
-    public synchronized boolean isComplete() {
-        return complete;
+    public boolean isComplete() {
+        synchronized (lock) {
+            return complete;
+        }
     }
 
-    public synchronized void setComplete() {
-        complete = true;
-        this.notifyAll();
+    public void setComplete() {
+        synchronized (lock) {
+            complete = true;
+            lock.notifyAll();
+        }
     }
 
-    public synchronized void close() {
-        for (DiskChunk dc : chunks) {
-            dc.release();
+    public void close() {
+        synchronized (lock) {
+            for (DiskChunk dc : chunks) {
+                dc.release();
+            }
+            chunks.clear();
+            complete = true;
         }
-        chunks.clear();
-        complete = true;
     }
 
     private DiskChunk oldestChunk() throws InterruptedException {
         while (true) {
-            synchronized (this) {
+            synchronized (lock) {
                 if (!chunks.isEmpty()) {
                     return chunks.pollLast();
                 }
                 if (complete) {
                     return null;
                 }
-                this.wait();
+                lock.wait();
             }
         }
     }
diff --git a/test/jdk/jdk/jfr/jvm/TestHiddenWait.java b/test/jdk/jdk/jfr/jvm/TestHiddenWait.java
new file mode 100644
index 0000000000000..f4b810f192e48
--- /dev/null
+++ b/test/jdk/jdk/jfr/jvm/TestHiddenWait.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.jfr.jvm;
+
+import java.nio.file.Path;
+import java.time.Duration;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicLong;
+
+import jdk.jfr.Recording;
+import jdk.jfr.Name;
+import jdk.jfr.Event;
+import jdk.jfr.FlightRecorder;
+import jdk.jfr.consumer.RecordedEvent;
+import jdk.jfr.consumer.RecordingStream;
+import jdk.test.lib.jfr.Events;
+
+/**
+ * @test TestHiddenWait
+ * @key jfr
+ * @summary Checks that JFR code don't emit noise in the form of ThreadSleep and JavaMonitorWait events.
+ * @requires vm.hasJFR
+ * @library /test/lib
+ * @run main/othervm jdk.jfr.jvm.TestHiddenWait
+ */
+public class TestHiddenWait {
+    static final String PERIODIC_EVENT_NAME = "test.Periodic";
+
+    @Name(PERIODIC_EVENT_NAME)
+    public static class PeriodicEvent extends Event {
+    }
+
+    public static void main(String... args) throws Exception {
+        FlightRecorder.addPeriodicEvent(PeriodicEvent.class,  () -> {
+            PeriodicEvent event = new PeriodicEvent();
+            event.commit();
+        });
+        try (Recording r = new Recording()) {
+            AtomicLong counter = new AtomicLong();
+            r.enable("jdk.ThreadSleep").withoutThreshold();
+            r.enable("jdk.JavaMonitorWait").withoutThreshold();
+            r.enable(PERIODIC_EVENT_NAME).withPeriod(Duration.ofMillis(100));
+            r.start();
+            // Triggers Object.wait() in stream barrier
+            try (RecordingStream b = new RecordingStream()) {
+                b.startAsync();
+                b.stop();
+            }
+            // Wait for for periodic events
+            try (RecordingStream s = new RecordingStream()) {
+                s.onEvent(PERIODIC_EVENT_NAME, e -> {
+                    if (counter.incrementAndGet() >= 2) {
+                        s.close();
+                    }
+                });
+                s.start();
+            }
+            List<RecordedEvent> events = Events.fromRecording(r);
+            for (RecordedEvent event : events) {
+                if (!event.getEventType().getName().equals(PERIODIC_EVENT_NAME)) {
+                    System.out.println(event);
+                    throw new Exception("Didn't expect ThreadSleep or JavaMonitorWait events");
+                }
+            }
+        }
+    }
+}