0

I just came across some code which uses wait-notify construct to communicate with thread defined in a class, by its other member-methods. Amusingly, after acquiring lock, all thread does in synchronized scope is timed-wait on same lock (see below snippet). Later, in non-synchronized scope, thread executes its key function (ie '//do something useful1').

My best guess at purpose of this mechanism is, to minimize thread's resource-consumption until call to 'someMethod' is made by other thread. What do experts think? If this is the case, what are better ways of achieving this behavior?

class SomeClass{
    public void run() {
        while (!isShuttingDown){
            try {
                synchronized (SomeClass.class) {
                    SomeClass.class.wait(500);
                }
            } catch (Throwable e) {
                LOGGER.info(SomeClass.class.getSimpleName() + " reaper thread interrupted", e);
            }
            //do something useful1
          }
    }


    public synchronized void someMethod(){
            //do something useful2
             synchronized (SomeClass.class) {
                SomeClass.class.notifyAll();
            }   
                   //do something useful3
    }
}
drop.in.ocean
  • 298
  • 2
  • 9
  • You haven't given us nearly enough context. The key parts will be in the "do something useful" bits. For example, this could be a producer/consumer queue, effectively. – Jon Skeet Oct 18 '13 at 14:37
  • I'd read up on this: http://stackoverflow.com/questions/37026/java-notify-vs-notifyall-all-over-again/37038#37038 – raffian Oct 18 '13 at 14:40
  • If I understand correctly, a producer/consumer will do some useful activity inside synchronized scope (i.e. after acquiring lock). But, in this case, there is nothing useful done inside synchronized scope. – drop.in.ocean Oct 18 '13 at 14:42
  • @drop.in.ocean: Well it would usually take the item to be processed from a queue, but that's all. This could be a *similar* situation, without being exactly the same. Fundamentally though, this does indeed make one thread wait until another has got to the middle part of `someMethod`. That's all we can say at the moment... – Jon Skeet Oct 18 '13 at 14:45
  • Why did you replace `catch (IOException ...` with `catch(Throwable ...` ? – artbristol Oct 18 '13 at 15:18
  • I guess, its done to catch any unexpected error and let that error not affect the execution of critical task in "//do something useful1". – drop.in.ocean Oct 18 '13 at 15:28
  • @drop.in.ocean It's better to let the unexpected error propagate - you don't know the state of the system, so "do something useful1" probably shouldn't run. – artbristol Oct 19 '13 at 07:35

2 Answers2

4

As described here,

The wait-notify pattern is used in a broad set of cases where one thread needs to tell other threads that some event has occurred. It is commonly used to implement a thread pool or producer-consumer scenario, where a particular thread or threads need to "pick up jobs" created by other threads (in this case, the "event" that has occurred is that a job has arrived for one of the threads to pick up).

Dark Knight
  • 8,218
  • 4
  • 39
  • 58
  • When quoting from [annother source](http://www.javamex.com/tutorials/wait_notify_how_to.shtml) you should ideally paraphrase it and provide a link to the resource. Even if the source permits word for word copying it should still be attributed and shown as a quote – Richard Tingle Oct 28 '13 at 16:07
1

after acquiring lock, all thread does in synchronized scope is timed-wait on same lock (see below snippet).

Yes, the pattern is strange. Typically I have a loop similar to that (although I always use a private final lockObject) that waits for a small amount of time because I don't want the method to spin -- performing its task too often.

I would have thought that the other method would lock on the same variable and then update the isShuttingDown flag. But doing the other // useful# sections is a strange pattern since there are a number of race conditions with the code that is going to make determining the order of the useful sections impossible.

Gray
  • 115,027
  • 24
  • 293
  • 354