• Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

making multiple threads sleep and waking them up

 
Chris Dancy
Ranch Hand
Posts: 136
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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.
 
Nicholas Jordan
Ranch Hand
Posts: 1282
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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?
 
Nitesh Kant
Bartender
Posts: 1638
IntelliJ IDE Java MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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.
 
Chris Dancy
Ranch Hand
Posts: 136
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Posts: 136
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Posts: 1282
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
 
Henry Wong
author
Marshal
Pie
Posts: 21015
78
C++ Chrome Eclipse IDE Firefox Browser Java jQuery Linux VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
 
Chris Dancy
Ranch Hand
Posts: 136
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Marshal
Pie
Posts: 21015
78
C++ Chrome Eclipse IDE Firefox Browser Java jQuery Linux VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Marshal
Pie
Posts: 21015
78
C++ Chrome Eclipse IDE Firefox Browser Java jQuery Linux VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Posts: 1282
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Posts: 136
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic