Hi, I am new this forum and to JAVA and am trying to understand Threads. I have certain questions regarding the use of signaling methods [wait() and notify()]. Let�s say, I have a class which has got a static instance counter. This static variable is incremented or decremented by calling different methods of this class. After the value is incremented we check if the counter exceeds a certain threshold. If it does, we are to make the calling instance wait() until someone notifies it. Whenever we decrement the counter, we notify all the objects waiting for a notification. Code:
Monu: If i understand you correctly, i am using different monitors for wait and notify and so there is no coherency in signaling.
Bang on! You got it rite
Monu: I am thinking of creating a static object in TheSignaler class(so that it is shared amongst thread instances) and then, using its monitor, call wait() and notify(). what say?
Yeah you can do that. Infact you can use ".class" variable for synchronization. In fact you can make your methods static synchronized (there is hardly any instance level state that you store).
Just a point, the operation "++" is not thread-safe per se. It may so happen that the value of the variable changes between (i + 1) and assigning to i. So, its better to use AtomicIntegers (or cousins thereof) for such counters.
Monu: Also, the condition around wait() and notify() concerns a static variable which can be altered anywhere in the program. Can this cause any problems?
I think you want the variable to be shared for all instances, rite? So you got to make it static. There is no problem in referring to a static variable in your guard condition. However, the comment that i have made above is something that you should incorporate.
BTW, what you are trying to do here is very close to what a Semaphore offers. You may want to use it or see the implementation to get hints.
I am using a ".class" monitor in the synchronized block and also, instead of using "++" and "--" on the primitive int "count" , i declared it as AtomicInteger and did an incrementAndGet() and decrementAndGet() instead...
The program runs and terminates without any exceptions, but no wait("Thread suspension") or "somebody waiting..." message gets printed.To see what was happening, i tried to print the value of count in the last statement of incrementOrStall() and decrementOrStall() methods; i got random values and sometimes even negative.Apparently, the guard condition is somehow not met.
However,i get count = 0 when i make the main Thread sleep sufficiently longer and then print the "count" value.
Monu: I still have not understood why the static counter gets negative values..
You are re-initializing "count" to zero in the TheSignaler constructor. You are creating a new instance of this class in the run() method i.e. a new instance for every thread run , so, the count is set to zero when every thread runs.
Additionally, since your print statements are outside the synchronized block, the values printed are not essentially what that thread was working upon. [ October 23, 2008: Message edited by: Nitesh Kant ]