Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations IamaSherpa on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Synchronizing and execution order

Status
Not open for further replies.

Diancecht

Programmer
Jan 8, 2004
4,042
ES
Hi all.

I'm currently involved in a (at least for me) obscure part of Java: synchronization.

I have some multithreaded apps that will want to access some resources all at a time and without interfernce.

My first thought was just use se synchornized keyword and let the JVM do its job but some other constraints forced me to design my own synchronization mechanism.

Of course, I'm not inventing the wheel so I'm using the old wait and notify methods.

My concern now is about execution order: the JVM spec says that once you wait() the order followed to notify() is not guaranteed. That looks pretty random for me.

I've used all this stuff for ages without no problem, and I think I will ignore this again but ... does anyone have experience with this in terms of changed execution order?

Cheers,
Dian
 
What were the constraints which forced you to use your own mechanism, Dian?

Tim
---------------------------
"Your morbid fear of losing,
destroys the lives you're using." - Ozzy
 
One read() method.
One write() method.

I want ACID operations with:

- Simultaneous readings (Two or more readers at a time)
- Protected writings (If one writer, everyone else waits)

Cheers,
Dian

 
Dian,

I would maybe do something a bit like this :

Code:
public class TestSync {

        class Mutex {
                boolean lock = false;
                public void lock() {
                        lock = true;
                }

                public void unlock() {
                        lock = false;
                }

                public boolean isLocked() {
                        return lock;
                }
        }

        static Mutex mutex;

        public void read() {
                if (mutex.isLocked()) {
                        // If locked, then queue up the requests for read access.
                        // Careful about recursive stack errors though :)
                        try { Thread.sleep(1000); } catch (Exception e) { e.printStackTrace(); }
                        read();
                }

                // do stuff
        }

        public void write() {
                // on a write, then lock access for reads ...
                synchronized(mutex) {
                        mutex.lock();

                        // do stuff

                        mutex.unlock();

                }
        }
}

--------------------------------------------------
Free Java/J2EE Database Connection Pooling Software
 
Thanks for your answers.

That's pretty much my approach, but I wanted to avoid thread sleeping and substitute it with a wait() call.

The reason is that, if a write call locks the mutex, when it finish, the read calls have to wait a residual time. With wait and notifyAll, it would be inmediate.

Cheers,
Dian
 
I'm pretty sure Dian that Thread.wait() uses Thread.sleep() too - its just sleeping for milliseconds rather than seconds ...

--------------------------------------------------
Free Java/J2EE Database Connection Pooling Software
 
Looking again at Object.wait() (not Thread.wait() as I said earlier !), its a native call - so it will call the relative OS's threading API (dunno what its called in Win32, but I know that on Linux, Java uses the pthread API).

Anyway ... getting back to the point, there will be some kind of loop/sleep/check value in there somewhere, so I dont see the problem with using Thread.sleep() :)

--------------------------------------------------
Free Java/J2EE Database Connection Pooling Software
 
Difficult to know, both are native, but I expect wait to use some signaling mechanism.

Cheers,
Dian
 
nah, I bet it does a JNI callback to Thread.sleep() from the native side [rofl]

--------------------------------------------------
Free Java/J2EE Database Connection Pooling Software
 
To be sincere, I wouldn't be surprised :)

Anyway, back to the point, once you are locked, the order you're unlocked is again random, there could be even inanition (is this the word in english).

So, did anyone experience unordered calls when using the JNI-callback-full wait call?

Cheers,
Dian
 
I'm not sure Dian, but I'm pretty sure that the code I posted would suffice your needs - ie lock when writing, sleep read calls while writing and allow all other calls through .

--------------------------------------------------
Free Java/J2EE Database Connection Pooling Software
 
I'm pretty sure it doesn't :p

Code:
0.00 Write call 1 - begin
0.01 Read call 1 - begin (locked)
0.99 Write call 2 - begin (locked)
1.01 Read call 1 - wait and check - still locked
1.05 Write call 1 - end (unlock)
1.99 Write call 2 - wait and check - start (lock)
2.00 Write call 2 - end (unlock)
2.01 Read call 1 - wait and check - start

As you can see, the read call would read data updated in a moment after it was done.

I know I should accept it for the sake of simplicity, but ... did you ever see me doing something simple, nice or even logical? :p

This is my way to get a life, dealing with random behaviours of JVM. I think I'd go for an array with timestamped request if I don't find the info about wait and notify.

Thanks mate.

Cheers,
Dian
 
You're too hard to please ... I give up.

--------------------------------------------------
Free Java/J2EE Database Connection Pooling Software
 
How about a two flag mutex so that it can't be written to again until it has been read
Code:
	class WeirdMutex {
		boolean writable = true;
		boolean readable = false;//can't be read until there has been a write

		public void WriteLock() {
			writable = false;
		}

		public void ReadLock() {
			readable = false;
		}

		public void FinishWrite() {
			readable = True;
		}
		public void FinishRead() {
			writable = True;
			//to allow multi reads of a single write here
			//readable = True; 
		}

		public boolean isWritable() {
			return writable;
		}
		public boolean isReadable() {
			return readable;
		}
	}

"If it could have gone wrong earlier and it didn't, it ultimately would have been beneficial for it to have." : Murphy's Ultimate Corollary
 
That would block the second writing until a reading is performed.

I want actions to be executed in the same order they are coming.

Thank you all for your help.

Cheers,
Dian
 
Yeah, there are plenty of algorithms to do this. In fact, I think that I've found the one I need.

My concern is not the algorithm itself, but the synchronization tecniques behind it, i.e. how do I make a thread be quiet.

I think I'll end using wait and notify, as always. wait's contract says that the can be "notified" in different order than they were slept.

That's my concern, but now I think I'm going too deep and too far, myabhe I should use them as everyone does without caring on that contract.

I was hoping someone had my same concern, but I see no one has, no it seems it's not an actual good concern :)

Cheers,
Dian
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top