[concurrency-interest] Impossible Exception?

Kevin Condon conivek at gmail.com
Mon Jan 14 09:21:19 EST 2008


Oops, a colleague just pointed out that I missed the "obj == null"
check.  Never mind.

Kevin

On Jan 14, 2008 8:25 AM, Kevin Condon <conivek at gmail.com> wrote:
> 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