Bill Roper (billroper) wrote,
Bill Roper

Locked Tight

Meanwhile, back in the wonderful world of Java:

Java allows you to declare classes inside of classes. Those classes have access to the internal protected members of each other, which is a handy way of circumventing the absence of "friend" classes when you've got a group of related classes that actually need access to those protected members. And it allows me to hide away any of those inner classes that I choose so that other classes in and out of the package can't get access to them.

So what's that good for?

Well, enforcing locking of objects, for one thing.

Let's assume an outer object that other classes will want to use. In this example, we'll call it a Thing. The Thing object itself is immutable so that it cannot be changed, but it contains an inner class, Thing.Mutable, that contains all of the methods that can change a Thing. This will be important in a moment.

The Thing object also contains an inner class, Thing.Lock, that can be used to acquire either a read or a write lock on a Thing. Each Thing has a unique ThingID that can be used to look up a Thing when it is passed to the Thing.Lock class, which will provide access to either a Thing or a Thing.Mutable depending on whether the user requested a read lock or a write lock. Internally, a Thing is stored as a Thing.Mutable, but we'll cast the reference to a Thing before handing it to the user if they've gotten a read lock. (Yes, they could cast the Thing back to a Thing.Mutable, but if they do that, then I cannot help them. :) )

The only way to gain access to a Thing is to use the Thing.Lock class to acquire a read or a write lock. Of course, all of those Things need to be stored somewhere. Thus, the Thing class has another inner class, which is the Thing.Catalog and which holds all of the Things. This class is protected so that you can't access it from outside the Thing class.

The Thing.Catalog class is immutable, but -- like the Thing class! -- it contains an inner Thing.Catalog.Mutable class and a Thing.Catalog.Lock class. In this particular implementation, the Thing.Catalog is a singleton, so there's only one instance in the application that holds all of the Things.

So let's add a new Thing to the Thing.Catalog. All we do is create a new Thing and call its catalog() method. Since the catalog() method is internal to Thing, it can access the protected Thing.Catalog and obtain a Thing.Catalog.Lock for writing, giving access to the Thing.Catalog.Mutable. This allows us to add the new entity to the Thing.Catalog without ever exposing the Thing.Catalog to an external user -- because if we did expose the Thing.Catalog, then an external user could look up a Thing without getting a lock on the Thing simultaneously. And that would be bad, even if they did have to use the Thing.Catalog.Lock to do it. :)

The happy news is that these objects can inherit most of the locking code from an abstract base class, so you don't have to write a lot of new code in any given Thing to support this. My Thing class is in a file that's only about 275 lines long (with lots of blank lines for readability, but not yet any Javadocs), despite having five different inner (or inner inner) classes.

And it does what I want it to do, which is also happy news.
Tags: computers, java, musings, work

  • Let's Try That Again

    For a variety of reasons, today ended up being moderately annoying. This is despite having made good progress on a number of fronts, so maybe I just…

  • Gentlemen, Be Seated

    I appear to collect office chairs. A few years ago, I bought a new chair for the studio in the after-Christmas sales. It is a big and tall Sealy…

  • Scheduling

    We got the heads up yesterday about the upcoming schedule for our kitchen renovation. The cabinet installers will be back on Saturday to finish up…

  • Post a new comment


    Anonymous comments are disabled in this journal

    default userpic

    Your reply will be screened

    Your IP address will be recorded