Thread.run()

by Charles Miller on March 31, 2003

I was hanging around at work late, doing a few practical checks on the effects of different isolation levels on overlapping entity bean accesses under Websphere. Oh, the exciting things I get up to in my day-job!

Anyway, the methodology was pretty basic. I had an Entity Bean with two fields. I had a session bean implementing the Command pattern. I had a JUnit test that would throw two commands at the session bean in different threads. By putting delays in the command objects, I could overlap the EJB writes in different ways and then test the outcome.

I know, all the answers to these things are in The Fine Manual, but sometimes it's just better to remove all doubt. It's like that Knuth quote: “Beware of bugs in the above code. I have only proven it correct, not tested it.”

Anyway, the most bizarre thing happened when I ran the tests. No matter what I did, I couldn't get two threads to enter the session bean at the same time. Now I know this is wrong. I messed around with transaction settings. I changed the timing a bit. I thought maybe it was a resource-allocation issue, and the cut-down version of Websphere running inside the IDE was being frugal with bean instances. I checked the spec, which helpfully told me that a container should either allocate a new bean, or throw a RemoteException, nothing in between.

It was while I was writing code to spam the session-bean with about 50 requests in an attempt to convince it to spawn more damn instances that I noticed my mistake. Thread.run() is not the same as Thread.start(). The requests were being processed serially because I was sending them serially. I was never spawning multiple threads.

I was going to rant about how this is all bad design on the part of the Thread class. Maybe it is. But in truth, I'm just an idiot.

Previously: Testing private methods (don't do it)

Next: Revolutions are not imposed from above.