Browse Source

Repeatedly check status while trying to lock for shutdown

Closes gh-36260
pull/36273/head
Juergen Hoeller 2 months ago
parent
commit
20970a4a37
  1. 35
      spring-context/src/main/java/org/springframework/context/support/AbstractApplicationContext.java

35
spring-context/src/main/java/org/springframework/context/support/AbstractApplicationContext.java

@ -27,6 +27,7 @@ import java.util.Locale; @@ -27,6 +27,7 @@ import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
@ -1070,11 +1071,9 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader @@ -1070,11 +1071,9 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
this.shutdownHook = new Thread(SHUTDOWN_HOOK_THREAD_NAME) {
@Override
public void run() {
if (isStartupShutdownThreadStuck()) {
active.set(false);
if (!tryLockForShutdown()) {
return;
}
startupShutdownLock.lock();
try {
doClose();
}
@ -1087,6 +1086,30 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader @@ -1087,6 +1086,30 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
}
}
/**
* Try to acquire the common startup/shutdown lock, backing out if
* the main startup/shutdown thread is stuck or on interruption.
* @see #isStartupShutdownThreadStuck()
*/
private boolean tryLockForShutdown() {
try {
while (!this.startupShutdownLock.tryLock(100, TimeUnit.MILLISECONDS)) {
if (!this.active.get() || this.closed.get()) {
return false;
}
if (isStartupShutdownThreadStuck()) {
this.active.set(false);
return false;
}
}
return true;
}
catch (InterruptedException ex) {
Thread.currentThread().interrupt();
return false;
}
}
/**
* Determine whether an active startup/shutdown thread is currently stuck,
* for example, through a {@code System.exit} call in a user component.
@ -1098,7 +1121,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader @@ -1098,7 +1121,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
activeThread.interrupt();
try {
// Leave just a little bit of time for the interruption to show effect
Thread.sleep(1);
Thread.sleep(10);
}
catch (InterruptedException ex) {
Thread.currentThread().interrupt();
@ -1120,12 +1143,10 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader @@ -1120,12 +1143,10 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
*/
@Override
public void close() {
if (isStartupShutdownThreadStuck()) {
this.active.set(false);
if (!tryLockForShutdown()) {
return;
}
this.startupShutdownLock.lock();
try {
this.startupShutdownThread = Thread.currentThread();

Loading…
Cancel
Save