aspose file tools
The moose likes Threads and Synchronization and the fly likes Guarded Objects & NotifyAll() Big Moose Saloon
  Search | Java FAQ | Recent Topics
Register / Login
JavaRanch » Java Forums » Java » Threads and Synchronization
Reply Bookmark "Guarded Objects & NotifyAll()" Watch "Guarded Objects & NotifyAll()" New topic
Author

Guarded Objects & NotifyAll()

Frank Schawillie
Greenhorn

Joined: Dec 29, 2004
Posts: 2
Ok I must have missed sometime very obvious. I�m trying to create a guarded Thread() that will only execute when the Thread() counter is less than set max value.

The first three threads fall into the execute state and the next three threads will go into a wait state. This is what I wanted; the issue is on completion of an executing thread, I expected that the NotifyAll() would wake one of the waiting threads but it�s not?

thanxs

public class GuardedObject extends Thread {

private String name;
private static final int maxNumberOfActiveThreads = 3;
private static int currentNumberOfActiveThreads = 0;

GuardedObject(String name) {
this.name = name;
}

public void run() {
boolean loopControl = true;
while (loopControl) {
try {
if (currentNumberOfActiveThreads < maxNumberOfActiveThreads) {
currentNumberOfActiveThreads++;
System.out.println(this.name + ": Running!!");
for (int i = 0; i < 1000; i++) {
System.out.println(this.name + " :" + i);
}
synchronized (this) {
currentNumberOfActiveThreads--;
loopControl = false;
notifyAll();
System.out.println(this.name + ": Current number of active threads are: " + currentNumberOfActiveThreads);
}
} else {
synchronized (this) {
System.out.println(this.name + ": Too many active Threads");
wait();
}
}
} catch (InterruptedException e) {
System.out.println(this.name + ": I'm going to try again!");
}
}
}

public static void main(String[] args) {
GuardedObject a = new GuardedObject("a");
GuardedObject b = new GuardedObject("b");
GuardedObject c = new GuardedObject("c");
GuardedObject d = new GuardedObject("d");
GuardedObject e = new GuardedObject("e");
GuardedObject f = new GuardedObject("f");
a.start();
b.start();
c.start();
d.start();
e.start();
f.start();
}
}
Alan Walker
Greenhorn

Joined: Feb 15, 2004
Posts: 26
I would say the problem is that notifyAll is being executed on a different object (a different instance of the GuardedObject class) from the objects on which wait calls are being executed. So if object "d" is waiting, via effectively a call to this.wait(), it needs a call to the notifyAll method of the same object, "d". A call to the notifyAll() method of object "a" will not do the trick.


Chihuahua - Ajax-powered online word puzzle, <a href="http://chi.lexigame.com" target="_blank" rel="nofollow">http://chi.lexigame.com</a> <br />Letterbox Word Game Online, <a href="http://letterbox.lexigame.com" target="_blank" rel="nofollow">http://letterbox.lexigame.com</a> <br />Lexi Word Game for Java-enabled phones, <a href="http://www.lexigame.com" target="_blank" rel="nofollow">http://www.lexigame.com</a>
Stan James
(instanceof Sidekick)
Ranch Hand

Joined: Jan 29, 2003
Posts: 8791
I agree. Try adding another static variable, say a String called "lock". Synchronize on lock and then lock.notifyAll() when you're done. Since it's static, all instances will be synchronizing on the same object.

Going at another angle ... if your true objective is to never run more than three of something at a time, look into thread pooling with Executor in JDK 5. You set up an executor with three threads and put any number of commands into a queue. Each thread will run one command and then try to get another command from the queue. As an added advantage you set up and tear down only three threads, not six (or six thousand depending on your application). It's generally cheaper to create more commands and fewer threads.
[ December 30, 2004: Message edited by: Stan James ]

A good question is never answered. It is not a bolt to be tightened into place but a seed to be planted and to bear more seed toward the hope of greening the landscape of the idea. John Ciardi
Frank Schawillie
Greenhorn

Joined: Dec 29, 2004
Posts: 2
Thanxs for your suggestions! I have modified the code base on your comments and it not works great!

Here is the final version & again thanxs 4 the help..

public class GuardedObject extends Thread {

private String name;
private static final int maxNumberOfActiveThreads = 3;
private static int currentNumberOfActiveThreads = 0;
private static Object lock = new Object();

GuardedObject(String name) {
this.name = name;
}

public void run() {
boolean loopControl = true;
while (loopControl) {
try {
if (currentNumberOfActiveThreads < maxNumberOfActiveThreads) {
currentNumberOfActiveThreads++;
System.out.println(this.name + ": Running!!");
for (int i = 0; i < 1000; i++) {
System.out.println(this.name + " :" + i);
}
synchronized (lock) {
currentNumberOfActiveThreads--;
loopControl = false;
lock.notifyAll();
System.out.println(this.name + ": Current number of active threads are: " + currentNumberOfActiveThreads);
}
} else {
synchronized (lock) {
System.out.println(this.name + ": Too many active Threads");
lock.wait();
}
}
} catch (InterruptedException e) {
System.out.println(this.name + ": I'm going to try again!");
}
}

public static void main(String[] args) {
GuardedObject a = new GuardedObject("a");
GuardedObject b = new GuardedObject("b");
GuardedObject c = new GuardedObject("c");
GuardedObject d = new GuardedObject("d");
GuardedObject e = new GuardedObject("e");
GuardedObject f = new GuardedObject("f");
a.start();
b.start();
c.start();
d.start();
e.start();
f.start();
}
Henry Wong
author
Sheriff

Joined: Sep 28, 2004
Posts: 16695
    
  19

Thanxs for your suggestions! I have modified the code base on your comments and it not works great!


It may works great -- or not, but there are definitely problems... Take a look at this code snippet.



You are reading and changing the currentNumberOfActiveThreads variable, but you are not protecting it with the lock you created. The scope that you are using to grab the lock for the wait/notify method is too small. It either needs to be increased to encompass the changing variables -- or new locks needs to be created. (I would choose increasing the scope in this case)

Henry


Books: Java Threads, 3rd Edition, Jini in a Nutshell, and Java Gems (contributor)
Henry Wong
author
Sheriff

Joined: Sep 28, 2004
Posts: 16695
    
  19

Another point, there is no reason to use notifyAll(). The notify() method is good enough. An exiting thread only needs to wake up one thread to replace it.

Henry
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Guarded Objects & NotifyAll()
 
Similar Threads
Threads and Synchronization examples
New question on K&B Chapter 9 Question 2
Behavior of wait()
Q on thread at Jxam
Synchronizing between two threads, one implements Runnable the other extends Thread