Browse Source

AbstractApplicationContext uses AtomicBoolean instead of synchronization for active/closed flags

Issue: SPR-11863
pull/573/head
Juergen Hoeller 11 years ago
parent
commit
fac2d80054
  1. 49
      spring-context/src/main/java/org/springframework/context/support/AbstractApplicationContext.java

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

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2013 the original author or authors. * Copyright 2002-2014 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -26,6 +26,7 @@ import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
@ -169,13 +170,10 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
private long startupDate; private long startupDate;
/** Flag that indicates whether this context is currently active */ /** Flag that indicates whether this context is currently active */
private boolean active = false; private final AtomicBoolean active = new AtomicBoolean();
/** Flag that indicates whether this context has been closed already */ /** Flag that indicates whether this context has been closed already */
private boolean closed = false; private final AtomicBoolean closed = new AtomicBoolean();
/** Synchronization monitor for the "active" flag */
private final Object activeMonitor = new Object();
/** Synchronization monitor for the "refresh" and "destroy" */ /** Synchronization monitor for the "refresh" and "destroy" */
private final Object startupShutdownMonitor = new Object(); private final Object startupShutdownMonitor = new Object();
@ -504,10 +502,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
*/ */
protected void prepareRefresh() { protected void prepareRefresh() {
this.startupDate = System.currentTimeMillis(); this.startupDate = System.currentTimeMillis();
this.active.set(true);
synchronized (this.activeMonitor) {
this.active = true;
}
if (logger.isInfoEnabled()) { if (logger.isInfoEnabled()) {
logger.info("Refreshing " + this); logger.info("Refreshing " + this);
@ -785,9 +780,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
* @param ex the exception that led to the cancellation * @param ex the exception that led to the cancellation
*/ */
protected void cancelRefresh(BeansException ex) { protected void cancelRefresh(BeansException ex) {
synchronized (this.activeMonitor) { this.active.set(false);
this.active = false;
}
} }
@ -862,13 +855,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
* @see #registerShutdownHook() * @see #registerShutdownHook()
*/ */
protected void doClose() { protected void doClose() {
boolean actuallyClose; if (this.active.get() && this.closed.compareAndSet(false, true)) {
synchronized (this.activeMonitor) {
actuallyClose = this.active && !this.closed;
this.closed = true;
}
if (actuallyClose) {
if (logger.isInfoEnabled()) { if (logger.isInfoEnabled()) {
logger.info("Closing " + this); logger.info("Closing " + this);
} }
@ -900,9 +887,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
// Let subclasses do some final clean-up if they wish... // Let subclasses do some final clean-up if they wish...
onClose(); onClose();
synchronized (this.activeMonitor) { this.active.set(false);
this.active = false;
}
} }
} }
@ -935,9 +920,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
@Override @Override
public boolean isActive() { public boolean isActive() {
synchronized (this.activeMonitor) { return this.active.get();
return this.active;
}
} }
/** /**
@ -950,14 +933,12 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
* no-op if {@link #getBeanFactory()} itself throws an exception in such a case. * no-op if {@link #getBeanFactory()} itself throws an exception in such a case.
*/ */
protected void assertBeanFactoryActive() { protected void assertBeanFactoryActive() {
synchronized (this.activeMonitor) { if (!this.active.get()) {
if (!this.active) { if (this.closed.get()) {
if (this.closed) { throw new IllegalStateException(getDisplayName() + " has been closed already");
throw new IllegalStateException(getDisplayName() + " has been closed already"); }
} else {
else { throw new IllegalStateException(getDisplayName() + " has not been refreshed yet");
throw new IllegalStateException(getDisplayName() + " has not been refreshed yet");
}
} }
} }
} }

Loading…
Cancel
Save