my dog learned polymorphism*
The moose likes Threads and Synchronization and the fly likes making multiple threads sleep and waking them up Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of OCM Java EE 6 Enterprise Architect Exam Guide this week in the OCMJEA forum!
JavaRanch » Java Forums » Java » Threads and Synchronization
Bookmark "making multiple threads sleep and waking them up" Watch "making multiple threads sleep and waking them up" New topic
Author

making multiple threads sleep and waking them up

Chris Dancy
Ranch Hand

Joined: Feb 14, 2006
Posts: 136
so here is the code layout, in a bit simpler form so please do not judge!!!

Lock lock = new ReentrantLock();

new Thread(new my1Runner(lock));
new Thread(new my2Runner(lock));
new Thread(new my3Runner(lock));

// In each of these classes the run method looks like this:

public void run(){
boolean running = true;
while(running){
if(lock.tryLock()){
//do something special
lock.unlock();
}
else{
try{
wait();
}catch(InterruptedException e){
System.out.println(e);
}
}
wakeUpAllOtherThreads();


The basic idea is for the lock to be shared among many threads. When the thread wants to do the special something special. It acquires the lock and does what it needs to and then releases it. I want all the other threads who cannot acquire the lock to wait indefinitely until they are woken up. This of course produces an error of MonitorStateException which has to do with the threads not owning the lock not being able to call wait. So im simply wondering how do I get around this, or am I just doing this wrong? I want all the other threads to wait if they cannot acquire the lock if that is possible, and not to be awoken until i say so.


("Anger is not an emotion, its a symptom of fear.")
Nicholas Jordan
Ranch Hand

Joined: Sep 17, 2006
Posts: 1282
Design is really good start, and you are thinking about the right things. Waht you want to avoid is a hard wait - aka spinlock - coded in by you....possibly inadvertently. The wait() supplied by the Java Virtual Machine should not be a spin-lock, they know too much about compilers and threading and so on to do it that way.

Originally posted by Chris Dancy:
(...snip...)So im simply wondering how do I get around this, or am I just doing this wrong? I want all the other threads to wait if they cannot acquire the lock if that is possible, and not to be awoken until i say so.


Awakening all waiting threads and only one getting a slot is wasteful if the design has to scale. You can stack up the requests somhow, I just use synchronized and allocate the workload such that only one thread can enter at a time. If you have to have a lock, then there is some shared resource that needs a lock. Trying to write a scheduler from the application side is potentially backwards, thus the system supplied wait() may be just the thing.

wakeUpAllOtherThreads(); is notifiy() { I am pretty sure, but that is from memeory } any tryLock() is potentially hiding deadlocks and has to be examined with the strongest tools available.

Why not just use synchronized at entry?


"The differential equations that describe dynamic interactions of power generators are similar to that of the gravitational interplay among celestial bodies, which is chaotic in nature."
Nitesh Kant
Bartender

Joined: Feb 25, 2007
Posts: 1638

Nicholas:
tryLock() is potentially hiding deadlocks and has to be examined with the strongest tools available.

From the explanation and code provided, it looks like that the entire program is restricted to only one lock object. So, the question of deadlock does not arise.

I have a hunch that you are starting some threads to execute a set of tasks. Whenever a task is submitted, all the threads compete to get the task and execute.
If this is what you are trying to do, then using a ThreadPool will be correct way to go.
JDK5 has a set of concurrent classes(java.util.concurrent package) that has various flavors of threadpools. If you are on a version before that, then you can use the backport concurrent util library.


apigee, a better way to API!
Chris Dancy
Ranch Hand

Joined: Feb 14, 2006
Posts: 136
I do want the threads that dont get the lock to go into a period of waiting, using the wait(). all threads that are waiting get put into an array, to be used for something else while they are waiting for the lock. Though if nothing else doesent need them at the time, I simply want them to wait forever, so to speak. I wanted to do something like:

if(!lock.tryLock())
wait();
else
//Do some special code.

This of course throws the exception if the thread does not currently own the lock. But that is in its basic form what I currently need.
Chris Dancy
Ranch Hand

Joined: Feb 14, 2006
Posts: 136
And im def not doing a spinlock, that would consume way too much cpu cycles for the amount of threads possibly having to wait.
Nicholas Jordan
Ranch Hand

Joined: Sep 17, 2006
Posts: 1282
Henry Wong
author
Sheriff

Joined: Sep 28, 2004
Posts: 18765
    
  40

Originally posted by Chris Dancy:
I do want the threads that dont get the lock to go into a period of waiting, using the wait(). all threads that are waiting get put into an array, to be used for something else while they are waiting for the lock. Though if nothing else doesent need them at the time, I simply want them to wait forever, so to speak. I wanted to do something like:

if(!lock.tryLock())
wait();
else
//Do some special code.

This of course throws the exception if the thread does not currently own the lock. But that is in its basic form what I currently need.


The tryLock() method has a variant that does close to what you want. You can specify a timeout period to keep trying -- basically, it is internally using wait() and retrying, instead of spinning.

If you want to retry forever, then you can just use the lock() method, which does the same thing, with a timeout of infinity.

Henry


Books: Java Threads, 3rd Edition, Jini in a Nutshell, and Java Gems (contributor)
Chris Dancy
Ranch Hand

Joined: Feb 14, 2006
Posts: 136
Thats the thing, I dont want each thread to keep testing the lock to see if its held, I simply want one test to see if the lock is available and if its not, wait forever until its woken up, not keep going through the cycle of checking
Henry Wong
author
Sheriff

Joined: Sep 28, 2004
Posts: 18765
    
  40

and if its not, wait forever until its woken up, not keep going through the cycle of checking


Then the trylock and wait are completely independant of each other. You can declare a shared object, just so that you can grab the sync lock, and wait for notification. Like so....

Henry Wong
author
Sheriff

Joined: Sep 28, 2004
Posts: 18765
    
  40

And of course, you should use some sort of check flag, as the wait() can wakeup prematurely....



Henry
[ June 06, 2008: Message edited by: Henry Wong ]
Nicholas Jordan
Ranch Hand

Joined: Sep 17, 2006
Posts: 1282
Making notDone available from some sort of controller. Design depends somewhat on how many locks and so on,... how heavily the system is loaded and reliability factors that determine how robust a design is needed.
Chris Dancy
Ranch Hand

Joined: Feb 14, 2006
Posts: 136
ok I now see where my initial design thought was wrong. Thank you henry for pointing it out, thats what I was looking for, though I did not know it. After playing a bit, I've gotten what I need to work, working. So thanks to everyone for helping me out, as well as the other folks who got me thinking in the right direction.

Sincerely,
Chris Dancy
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: making multiple threads sleep and waking them up