Wednesday, March 4, 2009

Java and RAII

I admit, I've partaken in the endless holy wars between Java and C++. I being a C++ programmer have always been all to willing to trash on Java. I've been particular aware of Java's failing as I'm working the the book, Java Concurrency in Practice.

Java is great language, C++ is a great language. They both target different problems. Those problems overlap in some areas. Before trashing on a language it's vital understand where they are coming from. But all this is rant for a different time.

Java's greatest strength turns out to be its greatest weakness. I'm talking about the garbage collector, and more generally resource management. There is no doubt that Java's GC is amazing. I may go so far as to say that is superior to smart pointers. Java's intrinsic synchronization (the synchronized keyword ) is also amazing. Both of these elegantly solve a resource management problem. Here in lies Java's weakness. It solves A resource management problem. There are many, arbitrary many: Java's new explicit locking primatives, DB resources, files system resources, Game objects, etc. Java beautifully solves the memory resource problem, and one class of synchronization managment, all other resources are left out in the cold.

public class Unclean
{
private final Lock m_lock = new ReentrantLock();

public void foo()
{
m_lock.lock();
try
{
// do synchronized stuff here.
}
finally
{
m_lock.unlock();
}
}
}

Compare this to a similar construct in C++0x
class Clean
{
private:
std::mutex m_mutex;

public:
void foo( void )
{
std::lock(m_mutex) l;

// do synchronized stuff here.
}
};

Here the differences are only minor, even so the C++ is more secure and easier to type. This becomes even more evident once multiple resources are acquired in the method.

Where RAII really shines however is when the object isn't collected in the location where it was declared. This is especially obvious with GameObjects, not just the memory used to store its state.

RAII resource management is powerful as it can be applied to all resource management task. Be the classics like memory, file/network IO, or synchronization. Of if the be more application specific like GameObjects, Textures, etc.