[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: the evils of multithreading
- To: <reason@exratio.com>, "Reason" <reason@exratio.com>,<ozone-users@ozone-db.org>
- Subject: Re: the evils of multithreading
- From: Falko Braeutigam <falko@smb-tec.com>
- Date: Mon, 4 Jun 2001 17:44:45 +0200
- Delivered-To: mail@smb-tec.com
- Delivered-To: softw7-ozone-db:org-ozone-users@ozone-db.org
- In-Reply-To: <EPEELOAJBJFJPKFALCGKAEEPCAAA.reason@exratio.com>
- Organization: SMB
- References: <EPEELOAJBJFJPKFALCGKAEEPCAAA.reason@exratio.com>
On Mon, 28 May 2001, Reason wrote:
> 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.
Of course not. Otherwise this would break transaction isolation. The results of
a transaction are shown to the outside when the transaction commits or never if
it aborts.
> 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)
This exception appears because the importantMethod is not marked as /*update*/
although it changes the object state by setting the mic variable. If you
correctly mark this method as update method then all other threads will be
blocked and wait until the first thread has completed its work - and no
exception will occur.
Falko
>
> 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/
--
______________________________________________________________________
Falko Braeutigam mailto:falko@smb-tec.com
SMB GmbH http://www.smb-tec.com