diff --git a/src/java.desktop/share/classes/java/awt/GraphicsEnvironment.java b/src/java.desktop/share/classes/java/awt/GraphicsEnvironment.java
index 0265142aee3..2e89aa6f672 100644
--- a/src/java.desktop/share/classes/java/awt/GraphicsEnvironment.java
+++ b/src/java.desktop/share/classes/java/awt/GraphicsEnvironment.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -23,7 +23,6 @@
  * questions.
  */
 
-
 package java.awt;
 
 import java.awt.image.BufferedImage;
@@ -36,7 +35,6 @@ import sun.font.FontManager;
 import sun.font.FontManagerFactory;
 import sun.java2d.HeadlessGraphicsEnvironment;
 import sun.java2d.SunGraphicsEnvironment;
-import sun.security.action.GetPropertyAction;
 
 /**
  *
diff --git a/src/java.desktop/windows/classes/sun/awt/PlatformGraphicsInfo.java b/src/java.desktop/windows/classes/sun/awt/PlatformGraphicsInfo.java
index 02527d4f207..4644a2e5f46 100644
--- a/src/java.desktop/windows/classes/sun/awt/PlatformGraphicsInfo.java
+++ b/src/java.desktop/windows/classes/sun/awt/PlatformGraphicsInfo.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2019, 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
@@ -28,20 +28,41 @@ package sun.awt;
 import java.awt.GraphicsEnvironment;
 import java.awt.Toolkit;
 
+import sun.awt.windows.WToolkit;
+
 public class PlatformGraphicsInfo {
 
+    private static final boolean hasDisplays;
+
+    static {
+        loadAWTLibrary();
+        hasDisplays = hasDisplays0();
+    }
+
+    @SuppressWarnings("removal")
+    private static void loadAWTLibrary() {
+        java.security.AccessController.doPrivileged(
+            new java.security.PrivilegedAction<Void>() {
+                public Void run() {
+                    System.loadLibrary("awt");
+                    return null;
+                }
+            });
+    }
+
+    private static native boolean hasDisplays0();
+
     public static GraphicsEnvironment createGE() {
         return new Win32GraphicsEnvironment();
     }
 
     public static Toolkit createToolkit() {
-        return new sun.awt.windows.WToolkit();
+        return new WToolkit();
     }
 
     public static boolean getDefaultHeadlessProperty() {
-        // On Windows, we assume we can always create headful apps.
-        // Here is where we can add code that would actually check.
-        return false;
+        // If we don't find usable displays, we run headless.
+        return !hasDisplays;
     }
 
     /*
@@ -54,5 +75,4 @@ public class PlatformGraphicsInfo {
             "\nThe application does not have desktop access,\n" +
             "but this program performed an operation which requires it.";
     }
-
 }
diff --git a/src/java.desktop/windows/classes/sun/awt/Win32GraphicsEnvironment.java b/src/java.desktop/windows/classes/sun/awt/Win32GraphicsEnvironment.java
index 04b3f7b77d7..cb7ab363cdf 100644
--- a/src/java.desktop/windows/classes/sun/awt/Win32GraphicsEnvironment.java
+++ b/src/java.desktop/windows/classes/sun/awt/Win32GraphicsEnvironment.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -60,7 +60,8 @@ public final class Win32GraphicsEnvironment extends SunGraphicsEnvironment {
         WToolkit.loadLibraries();
         // setup flags before initializing native layer
         WindowsFlags.initFlags();
-        initDisplayWrapper();
+
+        initDisplay();
 
         // Install correct surface manager factory.
         SurfaceManagerFactory.setInstance(new WindowsSurfaceManagerFactory());
@@ -82,20 +83,12 @@ public final class Win32GraphicsEnvironment extends SunGraphicsEnvironment {
     }
 
     /**
-     * Initializes native components of the graphics environment.  This
+     * Initializes native components of the graphics environment. This
      * includes everything from the native GraphicsDevice elements to
      * the DirectX rendering layer.
      */
     private static native void initDisplay();
 
-    private static boolean displayInitialized;      // = false;
-    public static void initDisplayWrapper() {
-        if (!displayInitialized) {
-            displayInitialized = true;
-            initDisplay();
-        }
-    }
-
     public Win32GraphicsEnvironment() {
     }
 
diff --git a/src/java.desktop/windows/native/libawt/windows/Devices.cpp b/src/java.desktop/windows/native/libawt/windows/Devices.cpp
index f36914e4606..e275cb77a57 100644
--- a/src/java.desktop/windows/native/libawt/windows/Devices.cpp
+++ b/src/java.desktop/windows/native/libawt/windows/Devices.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 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
@@ -85,60 +85,75 @@
 #include "Trace.h"
 #include "D3DPipelineManager.h"
 
+typedef struct {
+    int monitorCounter;
+    int monitorLimit;
+    HMONITOR* hmpMonitors;
+} MonitorData;
 
-/* Some helper functions (from awt_MMStub.h/cpp) */
 
-int g_nMonitorCounter;
-int g_nMonitorLimit;
-HMONITOR* g_hmpMonitors;
+// Only monitors where CreateDC does not fail are valid
+static BOOL IsValidMonitor(HMONITOR hMon)
+{
+    MONITORINFOEX mieInfo;
+    memset((void*)(&mieInfo), 0, sizeof(MONITORINFOEX));
+    mieInfo.cbSize = sizeof(MONITORINFOEX);
+    if (!::GetMonitorInfo(hMon, (LPMONITORINFOEX)(&mieInfo))) {
+        J2dTraceLn1(J2D_TRACE_INFO, "Devices::IsValidMonitor: GetMonitorInfo failed for monitor with handle %p", hMon);
+        return FALSE;
+    }
+
+    HDC hDC = CreateDC(mieInfo.szDevice, NULL, NULL, NULL);
+    if (NULL == hDC) {
+        J2dTraceLn2(J2D_TRACE_INFO, "Devices::IsValidMonitor: CreateDC failed for monitor with handle %p, device: %S", hMon, mieInfo.szDevice);
+        return FALSE;
+    }
+
+    ::DeleteDC(hDC);
+    return TRUE;
+}
 
 // Callback for CountMonitors below
-BOOL WINAPI clb_fCountMonitors(HMONITOR hMon, HDC hDC, LPRECT rRect, LPARAM lP)
+static BOOL WINAPI clb_fCountMonitors(HMONITOR hMon, HDC hDC, LPRECT rRect, LPARAM lpMonitorCounter)
 {
-    g_nMonitorCounter ++;
+    if (IsValidMonitor(hMon)) {
+        (*((int *)lpMonitorCounter))++;
+    }
+
     return TRUE;
 }
 
 int WINAPI CountMonitors(void)
 {
-    g_nMonitorCounter = 0;
-    ::EnumDisplayMonitors(NULL, NULL, clb_fCountMonitors, 0L);
-    return g_nMonitorCounter;
-
+    int monitorCounter = 0;
+    ::EnumDisplayMonitors(NULL, NULL, clb_fCountMonitors, (LPARAM)&monitorCounter);
+    return monitorCounter;
 }
 
 // Callback for CollectMonitors below
-BOOL WINAPI clb_fCollectMonitors(HMONITOR hMon, HDC hDC, LPRECT rRect, LPARAM lP)
+static BOOL WINAPI clb_fCollectMonitors(HMONITOR hMon, HDC hDC, LPRECT rRect, LPARAM lpMonitorData)
 {
-
-    if ((g_nMonitorCounter < g_nMonitorLimit) && (NULL != g_hmpMonitors)) {
-        g_hmpMonitors[g_nMonitorCounter] = hMon;
-        g_nMonitorCounter ++;
+    MonitorData* pMonitorData = (MonitorData *)lpMonitorData;
+    if ((pMonitorData->monitorCounter < pMonitorData->monitorLimit) && (IsValidMonitor(hMon))) {
+        pMonitorData->hmpMonitors[pMonitorData->monitorCounter] = hMon;
+        pMonitorData->monitorCounter++;
     }
 
     return TRUE;
 }
 
-int WINAPI CollectMonitors(HMONITOR* hmpMonitors, int nNum)
+static int WINAPI CollectMonitors(HMONITOR* hmpMonitors, int nNum)
 {
-    int retCode = 0;
-
     if (NULL != hmpMonitors) {
-
-        g_nMonitorCounter   = 0;
-        g_nMonitorLimit     = nNum;
-        g_hmpMonitors       = hmpMonitors;
-
-        ::EnumDisplayMonitors(NULL, NULL, clb_fCollectMonitors, 0L);
-
-        retCode             = g_nMonitorCounter;
-
-        g_nMonitorCounter   = 0;
-        g_nMonitorLimit     = 0;
-        g_hmpMonitors       = NULL;
-
+        MonitorData monitorData;
+        monitorData.monitorCounter = 0;
+        monitorData.monitorLimit = nNum;
+        monitorData.hmpMonitors = hmpMonitors;
+        ::EnumDisplayMonitors(NULL, NULL, clb_fCollectMonitors, (LPARAM)&monitorData);
+        return monitorData.monitorCounter;
+    } else {
+        return 0;
     }
-    return retCode;
 }
 
 BOOL WINAPI MonitorBounds(HMONITOR hmMonitor, RECT* rpBounds)
diff --git a/src/java.desktop/windows/native/libawt/windows/Devices.h b/src/java.desktop/windows/native/libawt/windows/Devices.h
index b6fd56a777f..0972ef1414e 100644
--- a/src/java.desktop/windows/native/libawt/windows/Devices.h
+++ b/src/java.desktop/windows/native/libawt/windows/Devices.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 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
@@ -74,4 +74,6 @@ static CriticalSection          arrayLock;
 
 BOOL WINAPI MonitorBounds (HMONITOR, RECT*);
 
+int WINAPI CountMonitors (void);
+
 #endif // _DEVICES_H_
diff --git a/src/java.desktop/windows/native/libawt/windows/awt_PlatformGraphicsInfo.cpp b/src/java.desktop/windows/native/libawt/windows/awt_PlatformGraphicsInfo.cpp
new file mode 100644
index 00000000000..638cd100b1f
--- /dev/null
+++ b/src/java.desktop/windows/native/libawt/windows/awt_PlatformGraphicsInfo.cpp
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2024 SAP SE. 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.
+ */
+
+#include <sun_awt_PlatformGraphicsInfo.h>
+#include "Devices.h"
+
+/*
+ * Class:     sun_awt_PlatformGraphicsInfo
+ * Method:    hasDisplays0
+ * Signature: ()Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_sun_awt_PlatformGraphicsInfo_hasDisplays0(JNIEnv *env, jclass thisClass) {
+    return CountMonitors() > 0 ? JNI_TRUE : JNI_FALSE;
+}
diff --git a/src/java.desktop/windows/native/libawt/windows/awt_Win32GraphicsDevice.cpp b/src/java.desktop/windows/native/libawt/windows/awt_Win32GraphicsDevice.cpp
index 74df808ee30..7712147c43c 100644
--- a/src/java.desktop/windows/native/libawt/windows/awt_Win32GraphicsDevice.cpp
+++ b/src/java.desktop/windows/native/libawt/windows/awt_Win32GraphicsDevice.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 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
@@ -179,7 +179,9 @@ void AwtWin32GraphicsDevice::Initialize()
     }
     gpBitmapInfo->bmiHeader.biBitCount = 0;
     HDC hBMDC = this->GetDC();
+    VERIFY(hBMDC != NULL);
     HBITMAP hBM = ::CreateCompatibleBitmap(hBMDC, 1, 1);
+    VERIFY(hBM != NULL);
     VERIFY(::GetDIBits(hBMDC, hBM, 0, 1, NULL, gpBitmapInfo, DIB_RGB_COLORS));
 
     if (colorData->bitsperpixel > 8) {
diff --git a/src/java.desktop/windows/native/libawt/windows/awt_Win32GraphicsEnv.cpp b/src/java.desktop/windows/native/libawt/windows/awt_Win32GraphicsEnv.cpp
index 6c949b564e9..9991427c75e 100644
--- a/src/java.desktop/windows/native/libawt/windows/awt_Win32GraphicsEnv.cpp
+++ b/src/java.desktop/windows/native/libawt/windows/awt_Win32GraphicsEnv.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 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
@@ -36,10 +36,8 @@
 BOOL DWMIsCompositionEnabled();
 
 void initScreens(JNIEnv *env) {
-
     if (!Devices::UpdateInstance(env)) {
         JNU_ThrowInternalError(env, "Could not update the devices array.");
-        return;
     }
 }
 
diff --git a/test/jdk/javax/swing/reliability/HangDuringStaticInitialization.java b/test/jdk/javax/swing/reliability/HangDuringStaticInitialization.java
index fc820a32fa1..d6666d21309 100644
--- a/test/jdk/javax/swing/reliability/HangDuringStaticInitialization.java
+++ b/test/jdk/javax/swing/reliability/HangDuringStaticInitialization.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 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,7 +33,6 @@ import java.nio.file.attribute.BasicFileAttributes;
 /**
  * @test
  * @bug 8189604 8208702
- * @requires !vm.debug | os.family != "windows"
  * @run main/othervm -Djava.awt.headless=false HangDuringStaticInitialization
  * @run main/othervm -Djava.awt.headless=true HangDuringStaticInitialization
  */