[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

the evils of multithreading




Synopsis:

In a multithreaded environment, you can't always create ozone objects in a
method that you plan to use later in that method. Synchronization won't fix
the problem, but putting object creation code in its own method will.

------

I thought I should share this one, given the two days of watching Ozone
blowing up that it took me to work things out. (Disclaimer -- all testing
done on Windows 2000). Assume the following is in an ObjectImpl class
extending OzoneObject implementing OzoneRemote, et al:

private mic = null;

public importantMethod(blah, blah) throws Exception
{

	[do stuff...]
	if(mic == null)
		mic =
(MyImportantClass)database.createObject(MyImportantClass.class.getName(),
access_level);

	[do stuff...]

	mic.doSomething();

	[do stuff...]

}

If you run two or three threads through this method at once, the new mic
object will not be visible by ID in the grand index of objects to any of the
threads until one of the threads exits the method and thus closes out the
transaction. The following exception (or something like it) will be thrown
at mic.doSomething() and entered into the Ozone log --

Transaction: ta(117): uncaught exception: (org.ozoneDB.ObjectNotFoundExc: No
such object ID: 129)

And then all hell will break loose by degrees. In my test code, I usually
end up locking up Ozone entirely after some nasty looking
NullPointerExceptions in the WizardStore and a deadlock.

Funnily enough, declaring segments or all of the code in importantMethod as
synchronized doesn't fix things. Declaring the method synchronized doesn't
fix things either -- although it does seem to narrow the margin by which
threads have to follow on each others heels in order to cause problems.

The fix in this case is to put the object creation in its own method; in
this case, the object will be available to other threads.

public importantMethod(blah, blah) throws Exception
{

	[do stuff...]

	if(mic == null)
		mic = createMic();

	[do stuff...]

	mic.doSomething();

	[do stuff...]

}


public createMic() throws Exception
{
	return
(MyImportantClass)database.createObject(MyImportantClass.class.getName(),
access_level);
}

Reason
http://www.exratio.com/