1

I cannot find The Problem Can Someone Help me.

public class Achterbahn {

private final Object monitor = new Object();

public   synchronized void test() throws InterruptedException {
    
    
        //monitor.wait();
        

        System.out.println("car");
        wait();
        System.out.println("car");
    
}

public  synchronized void Passagier() throws InterruptedException {
    Thread.sleep(2000);

    
        System.out.println("p");

        notify();
    
    //b.t1.notify();
    
    
}
public static void main(String []args) throws InterruptedException {
    

    Thread t4 = new Thread(new Runnable() {

        @Override
        public void run() {
            Achterbahn b = new Achterbahn();
            try {
                b.Passagier();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            
        }
        
    });
    Thread t5= new Thread(new Runnable() {
        
        @Override
        public void run() {
            Achterbahn b = new Achterbahn();
            try {
                b.test();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            
        }
        
    
    });
    
    
    new Thread(t4).start();
    new Thread(t5).start();     
      t5.join();
      t4.join();
    
}


   }

The output is: car p

it seems like notify is working i want print also car at the last but i donot konw why its not working

i hope Someone Help me. as soon as possible.

i have all methodes in the same class and i tried also sepreate classes but it didnt work

Umesh Sanwal
  • 681
  • 4
  • 13

3 Answers3

1

(I am guessing in this case that “it didn’t work” means the program hangs. Please be specific about what the issue you’re seeing is.)

There are 2 issues. One is that you are creating separate objects in each thread. The object that wait and notify are called on have to be the same, the monitor that is waited on is the one that needs to receive the notify. In this code the synchronized methods use the intrinsic lock on the instance that the methods are called on.

Create the object once in the main method, each thread needs to reference the same object.

The second issue, once you fix the first issue, will be a race condition. If the notify performed by one thread occurs first then when the wait executes the notify has already happened and the wait keeps waiting forever.

Add a condition variable to remember whether the notify occurred.

In general the pattern is to check the condition in a loop, see this question: Why we must use "while" for checking race condition not "if". The post has an example of using a variable to see if a condition occurred, here it

synchronized(obj)
{
    while (condition_not_matched)
    {
        obj.wait();
    }
    //continue
    dosomething();
}
Nathan Hughes
  • 94,330
  • 19
  • 181
  • 276
  • You call wait() on one thread and notify() on another thread. The thread with wait would never get the signal. You need to call notify on T5 – Don Ha Jan 04 '21 at 03:36
0

You're doing several things wrong.

  • only start a single instance of C. Then use that instance to invoke your methods. Different instances don't share monitors within synchronized methods
  • You're starting two new threads when you start them. Just start them as follows:
t4.start();
t5.start();

The primary problem is that t4 starts first and immediately sleeps. So t5 won't start until the sleep finishes. But by that time, the notify() for the wait in t4 has been issued before the wait() is invoked in t5 Thus the wait will never see it. So you need to give t4 a chance to start before the sleep occurs. There are several ways to fix this. One is to use a flag to signal that the other method is ready. But do not use a tight while loop. Put a sleep inside it for a small amount of time. I have provided an example below. I also assigned names to your threads to match your variables.



public class C {
    boolean ready = false;
    
    public synchronized void test() throws InterruptedException {
        System.out.println("Current thread = " + Thread.currentThread().getName());     
        ready = true;
        System.out.println("car");
        wait();
        System.out.println("car");
    }
    
    public synchronized void Passagier() throws InterruptedException {
        Thread.sleep(4000);
        System.out.println("Current thread = " + Thread.currentThread().getName());
        System.out.println("p");
        notify();
        
    }
    
    public static void main(String[] args)
            throws InterruptedException {
        C b = new C();
        Thread t4 = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    while(!b.ready) {
                        Thread.sleep(100);
                    }
                    b.Passagier();
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        },"t4");
        
        Thread t5 = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    b.test();
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            
        },"t5");
        System.out.println("Starting t4");
        t4.start();
        System.out.println("Starting t5");
        t5.start();
//      
        t5.join();
        t4.join();
        
    }
    
}
WJS
  • 36,363
  • 4
  • 24
  • 39
-1

This Code work for me I have now the while loop

public class C {

int i = 34;
public synchronized void test() throws InterruptedException {
    System.out.println("car");
    while(i == 34) {
         wait();
    }
   
    notify();
    System.out.println("car");
}

public synchronized void Passagier() throws InterruptedException {
    i = 55;
    System.out.println("p");
    
    notify();
    
}

public static void main(String[] args)
        throws InterruptedException {
    
    C b = new C();
    Thread t4 = new Thread(new Runnable() {
        @Override
        public void run() {
            try {
                b.Passagier();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    });
    Thread t5 = new Thread(new Runnable() {
        
        @Override
        public void run() {
            try {
                b.test();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            
        }
        
    });
    
    
   
    t4.start();
    t5.start();
    t4.join();
    t5.join();
    }
   }