Thursday, June 29, 2023

Horror Code: FIFO Stack and LIFO Queue

This article was originally posted on JRoller on February 4, 2014 

Recently, I found this class in one of our applications:

 public class FIFOStack extends Vector {

	public synchronized Object push(Object o) {
		add(o);
		return o;
	} 

	public synchronized Object pop() {
		if (isEmpty()) {
			return null;
		} 
		return remove(0);
	} 

	public synchronized boolean empty() {
		return isEmpty();
	} 
} 

I was imagining the developer thinking: "If only I had a class like Stack, except it would work in FIFO mode". The code is really old, so there was no Queue implementation in the JDK at this time. But still, definitions of Stacks and Queues are way older than the JDK.

Out of curiosity, I looked in the code for LIFO Queues. To my surprise, I found 2, both in the JDK itself. One caught my attention, due to the comment preceding it. See for yourself, in the SynchronousQueue class:

    
    /*
     * To cope with serialization strategy in the 1.5 version of
     * SynchronousQueue, we declare some unused classes and fields
     * that exist solely to enable serializability across versions.
     * These fields are never used, so are initialized only if this
     * object is ever serialized or deserialized.
     */

      

I do not have a Java 1.5 around to check, but if I understand correctly the comment, serialization of SynchronousQueue in Java 1.5 was too tied to its implementation. So when they changed it in Java 1.6, they had to create the old LifoWaitQueue internal class just so that serialization would work with previous Java versions. Backward compatiblity can make to ugly code sometimes. The funny part is that the internal LifoWaitQueue and FifoWaitQueue classes were replaced by TransferQueue and TransferStack. Even the best of us can make naming mistakes...

Of course, the important thing to understand this post is that Stacks are supposed to be LIFO, and Queues FIFO.
I checked on my Java 17 for the SynchronousQueue class, and this comment, together with its LifoWaitQueue, are still there in the code. Time for deprecation?

No comments:

Post a Comment