1

This is the part of my code,I am facing problems in using wait()

class Leader extends Thread {
    private Table table;
    synchronized public void run()
    {
        while(true)
        { 
            try
            {
                while(table.getResources()!=0)
                    wait();

                table.putResources(5); // here I am updating the value(I have a table class)
            } catch(InterruptedException e) { }
        }
    }
}


class Soldier extends Thread {

    public void run() 
    {
        while(true) 
        {
            try 
            {
                synchronized(this) 
                {

                    if(table.getResources()==this.need_Value)    //checking value of resource 
                    {
                        sleep(1000);
                        table.clearResources();      //this will put the value of resource to 0
                        notifyAll();
                    }
                }
            } catch(InterruptedException e) { }
        }
    }
}

So basically I have a thread of leader class and a thread of Leader class. Initially resources is 0 so in the Soldier class resources is updated to 5. Suppose now for Soldier class need_Value was 5,so it will update value of resources to 0. So now Leader class should again run as resources is 0,but actually it is still waiting. So is there anything wrong with my wait()?

PS- Assume I have Table class and all the constructors and variables used. I have omitted them because the code was too long

GameDroids
  • 5,584
  • 6
  • 40
  • 59
  • There is no `notify()` in your code. `wait()` will sleep until someone calls `notify()` or `notifyAll()` on the same object. – Piotr Praszmo Nov 15 '14 at 10:13
  • I have tried using notify() after clearing resources in soldier class but still it was waiting.I have editted the code with notify() –  Nov 15 '14 at 10:16
  • You must notify the leader. – Markus Malkusch Nov 15 '14 at 10:19
  • You need to synchronize, `wait()` and `notify()` on the same object in both threads. In your case probably on `table` object. – Piotr Praszmo Nov 15 '14 at 10:19
  • @Markus Malkusch I tried that but that also didnt help.Basically I want to resume Leader thread after clearResources of Soldier thread has run. –  Nov 15 '14 at 10:22
  • @Banthar On using wait and notify on table object,I am getting this error `Exception in thread "Leader Thread" java.lang.IllegalMonitorStateException at java.lang.Object.wait(Native Method) at java.lang.Object.wait(Unknown Source) at Leader.run(Leader.java:22)` –  Nov 15 '14 at 10:25
  • @Noober You need to use the `synchronize` keyword around a common object... – MadProgrammer Nov 15 '14 at 10:26

2 Answers2

2

You notify on another object than you wait.

Your Leader class synchronizes on this (implicitly because you put synchronized on the instance method). So your Leader waits on the Leader instance to be notified.

In your Soldier class you also synchronize on this and you notify on that Soldier instance.

But since you notify on the Soldier instance and the Leader waits on the Leader instance it will not get notified.

Both instances Soldier and Leader should use the same synchronization object.

You might want to fix this by using the Leader instance as synchronization object in the Soldier

class Soldier extends Thread {

    private Leader leader;

    public Soldier(Leader leader) {
        this.leader = leader;
    }

    public void run()
    {
        while(true)
        {
            try
            {
                synchronized(leader)
                {

                    if(table.getResources()==this.need_Value)    //checking value of resource
                    {
                        sleep(1000);
                        table.clearResources();      //this will put the value of resource to 0
                        leader. notifyAll();
                    }
                }
            } catch(InterruptedException e) { }
        }
    }
}
René Link
  • 48,224
  • 13
  • 108
  • 140
  • I have another doubt this was my main code- `Table table=new Table(0); Thread leader=new Leader("Leader",table); Thread ST1=new Soldier("Soldier",table,4) leader.start();ST1.start(); ` So I think both the threads were called on table object.So my code should have worked as the calling instance of both threads were the same i.e table –  Nov 15 '14 at 10:41
  • @Noober Both threads are created with the `Table` object, but they don't synchronize on it. If you want the table object to be the synchronization object you must use it explicitely in `Leader` and `Soldier`, e.g. `synchronized (table) { }`. This would also work. – René Link Nov 15 '14 at 10:46
  • Yes I tried using `synchronized(table)` and it worked,but my question is when I use `synchronized(this)` ,here `this` is the calling object which is `table` so these two statements should be equivalent or not?? –  Nov 15 '14 at 10:53
  • @Noober No, `this` refers to the current object, not the caller. That's why you are able to do something like `this.interrupt()` in your `Leader` class, because I guess `Table` doesn't have a method `interrupt()` ;) – René Link Nov 15 '14 at 10:57
  • Yes I dont have any `interrupt()` method in `Table`.I know `this` is the current object but are `this` and `Table` not same in this case?? Sorry,I am just a beginner and I am really grateful to you for helping me out. –  Nov 15 '14 at 11:07
  • `this` only refers to `Table` in the `Table` object. What you do is passing a reference of `Table` to the `Leader` and `Soldier`. Nevertheless the `this` reference inside `Leader` refers to the current `Leader` instance and not to the `Table`. Take a look at https://docs.oracle.com/javase/tutorial/java/javaOO/thiskey.html – René Link Nov 15 '14 at 11:11
0

Read the answer in this question: How to use wait and notify in Java? It explains in detail how to properly use the Wait() and Notify() functions.

Community
  • 1
  • 1
MSB
  • 854
  • 7
  • 24
  • If a question is a duplicate flag it as such rather than posting an answer. That way everything gets nicely linked together – Richard Tingle Nov 15 '14 at 10:55