Java’s Threading Tools
There is a lot to like about the threading model in Java. It's easy to make threads, it's decently fast, and it's stable. One thing that I wished they'd put into the JVM - or at least into javac like all the other 1.5/1.6 compiler 'hacks', is the idea that synchronization on a setter can be controlled by the instance variable itself. What I'm asking for is an automatic way to have javac create thread-safe setters and getters by simply naming the ivar.
The most obvious way of making a thread-safe setter is this:
/**
* This is the standard setter for the temperature
* of this instance.
*/
public synchronized void setTemp(double aTemp)
{
_temp = aTemp;
}
but the downside is that this means that if this instance is in a highly threaded environment, or there are other methods that take a significant amount of time to process, the ability to 'set' the temperature is dependent on the other synchronized methods on this class.
Sure, you can make an object to lock on and it might look like this:
private double _temp = 0;
private String _tempLock = "TempLock";
/**
* This is the setter for the temperature uses an
* additional ivar - a String, to protect multiple
* threads changing the value at once.
*/
public void setTemp(double aTemp)
{
synchronized (_tempLock) {
_temp = aTemp;
}
}
but then you have all these extra ivars that you have no real need for and no need to really put into the setter other than as a thread-safety mechanism.
Some will argue that if I had used a Double and not a double I could synchronize on the ivar itself. But it's not really safe doing that. You'd have to be careful of the null value and then what if you changed the reference within the synchronized block - you'd no longer be protected. No, there needs to be the ivar itself - allowing null, and then some mechanism to ensure thread safety on a more finer-grained level than locking the entire instance.
They need to have something that does the obvious things for an ivar of a given type. You want to save typing? Make something like this:
/**
* These create the setter and getter for the ivar
* '_temp' because the need to lock is implied
* on the setter and typically unnecessary on the
* getter (unless it's a long).
*/
public threadsafe setTemp(double aTemp) : private double _temp;
public threadsafe getTemp() : private double _temp;
/**
* These versions would create 'protected' versions
* of the getter and setter methods.
*/
protected threadsafe setTemp(double aTemp) : private _temp;
protected threadsafe getTemp() : private _temp;
/**
* This creates both setter and getter for the ivar
* '_temp' because the structure to create the two
* is clear from this information alone.
*/
public threadsafe accessors Temp : private double _temp;
The information to build the code for the setter and getter is clearly specified in the above examples. In the first set, the ivar _temp is clearly private, a double and the names of the methods to build are clear. There's even the argument type - which is really redundant, if you think about it.
A possibly even simpler solution would be to combine the definition of the ivar and the scope of the setter and getter in one statement - like the last example. That way, you would know the ivar's name, type, scope, and then the scope of the setter and getter. You could even allow one to use a PropertyChange system with listener registration, etc. This is not that hard, and I've used it in tons of classes. The clutter it'd save would be far far more than the collapsed for-loop.
Anyway, today I did a lot of the 'mutex' variables because I needed to remove as many synchronized methods as possible on a class I was working with. Virtually every one of them was a setter, and it was annoying to think that they made a goofy collapsed for-loop in 1.5, but they left this little nugget out.
Amazing. I think it shows to me that defensive programming is not heavily exercised by the Java Developers. Otherwise, they too, would be sick of making thread-safe but not lock greedy accessor methods.