[concurrency-interest] Impossible Exception?

Kevin Condon conivek at gmail.com
Mon Jan 14 08:25:34 EST 2008


Hi Sam,

Isn't the statement "constructing = false;" missing after
createObject() is invoked?  All get() calls after the first one will
throw the exception.

Regards,
Kevin

On Jan 13, 2008 8:44 PM,  <concurrency-interest-request at cs.oswego.edu> wrote:
> ---------- Forwarded message ----------
> From: "Sam Berlin" <sberlin at gmail.com>
> To: concurrency-interest at cs.oswego.edu
> Date: Fri, 11 Jan 2008 22:50:30 -0500
> Subject: [concurrency-interest] Impossible Exception?
> We have a simple class that's intended to lazily load a singleton,
> throwing an exception if it detects a circular construction
> dependency.  However, occasionally a bug report is sent with the
> exception being thrown, but the stack trace shows no sign of circular
> dependency.  This is the class:
>
> ---
> public abstract class AbstractLazySingletonProvider<T> implements Provider<T> {
>
>     /** The backing object. */
>     private T obj;
>
>     /** Whether or not construction has already started. */
>     private boolean constructing;
>
>     /** Retrieves the reference, creating it if necessary. */
>     public synchronized T get() {
>         if(obj == null) {
>             if(constructing)
>                 throw new IllegalStateException("constructing again!");
>             constructing = true;
>             obj = createObject();
>         }
>         return obj;
>     }
>
>     /** Creates the object this reference will use. */
>     protected abstract T createObject();
>
> }
> ---
>
> It protects against concurrent access by get() being synchronized, so
> another thread attempting to retrieve should block until the first one
> is done.  (Yes, this could potentially create deadlocks in
> multi-threaded circular access, but fortunately that isn't happening.)
>
> This is an example stack trace we're seeing:
> --
> java.lang.IllegalStateException: constructing again!
>     at org.limewire.concurrent.AbstractLazySingletonProvider.get(AbstractLazySingletonProvider.java:28)
>     at org.limewire.nio.ssl.SSLUtils.getTLSContext(SSLUtils.java:56)
>     at org.limewire.nio.ssl.TLSNIOSocket.initOutgoingSocket(TLSNIOSocket.java:85)
>     at org.limewire.nio.NIOSocket.<init>(NIOSocket.java:57)
>     at org.limewire.nio.ssl.TLSNIOSocket.<init>(TLSNIOSocket.java:45)
>     at org.limewire.nio.ssl.TLSSocketFactory.createSocket(TLSSocketFactory.java:17)
>     at org.limewire.nio.ssl.TLSSocketFactory.createSocket(TLSSocketFactory.java:13)
>     at org.limewire.net.LimitedSocketController.connectPlain(LimitedSocketController.java:75)
>     at org.limewire.net.SimpleSocketController.connect(SimpleSocketController.java:46)
>     at org.limewire.net.SocketsManagerImpl.connect(SocketsManagerImpl.java:48)
>     at com.limegroup.gnutella.connection.GnutellaConnection.initialize(GnutellaConnection.java:485)
>     at com.limegroup.gnutella.connection.GnutellaConnection.initialize(GnutellaConnection.java:453)
>     at com.limegroup.gnutella.ConnectionManagerImpl.initializeFetchedConnection(ConnectionManagerImpl.java:1893)
>     at com.limegroup.gnutella.ConnectionManagerImpl.access$1500(ConnectionManagerImpl.java:104)
>     at com.limegroup.gnutella.ConnectionManagerImpl$ConnectionFetcher.handleEndpoint(ConnectionManagerImpl.java:2340)
>     at com.limegroup.gnutella.HostCatcher.getAnEndpoint(HostCatcher.java:1039)
>     at com.limegroup.gnutella.ConnectionManagerImpl$ConnectionFetcher.connect(ConnectionManagerImpl.java:2285)
>     at com.limegroup.gnutella.ConnectionManagerImpl.adjustConnectionFetchers(ConnectionManagerImpl.java:1821)
>     at com.limegroup.gnutella.ConnectionManagerImpl.cleanupBrokenFetchedConnection(ConnectionManagerImpl.java:1915)
>     at com.limegroup.gnutella.ConnectionManagerImpl.access$1900(ConnectionManagerImpl.java:104)
>     at com.limegroup.gnutella.ConnectionManagerImpl$ConnectionFetcher.shutdown(ConnectionManagerImpl.java:2360)
>     at com.limegroup.gnutella.connection.GnutellaConnection$AsyncHandshakeConnecter.shutdown(GnutellaConnection.java:1257)
>     at org.limewire.net.LimitedSocketController$DelegateConnector.shutdown(LimitedSocketController.java:237)
>     at org.limewire.nio.AbstractNBSocket.shutdownObservers(AbstractNBSocket.java:535)
>     at org.limewire.nio.AbstractNBSocket.shutdown(AbstractNBSocket.java:515)
>     at org.limewire.nio.NIODispatcher.cancel(NIODispatcher.java:403)
>     at org.limewire.nio.NIODispatcher.access$1000(NIODispatcher.java:93)
>     at org.limewire.nio.NIODispatcher$Attachment.notifyTimeout(NIODispatcher.java:989)
>     at org.limewire.nio.timeout.TimeoutController.processTimeouts(TimeoutController.java:56)
>     at org.limewire.nio.NIODispatcher.process(NIODispatcher.java:656)
>     at org.limewire.nio.NIODispatcher.run(NIODispatcher.java:867)
>     at java.lang.Thread.run(Unknown Source)
> --
>
> Can anyone explain how the exception could possibly be thrown?  It's
> either something simple that I'm overlooking, or impossible
> behavior... but at this point, I can't tell.
>
> Thanks much,
>  Sam


More information about the Concurrency-interest mailing list