Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Semaphore synchronized wait() and notify() [closed]

I have codes below: this is to get knowledge of semaphore. The codes is Thread A first is waiting since b.wait() (making calling thread sleep), then get notified, Why the code has synchronized here? If no, it gives IllegalMontiorXXXXXXXXX exception.

public class ThreadA {
   public static void main(String[] args){
     ThreadB b = new ThreadB();
     b.start();

     synchronized(b){
        try{
            System.out.println("Waiting for b to complete...");
            b.wait();
        }catch(InterruptedException e){
            e.printStackTrace();
        }

        System.out.println("Total is: " + b.total);
    }
  }
}



class ThreadB extends Thread{
    int total;
    @Override
    public void run(){
        synchronized(this){
            for(int i=0; i<100 ; i++){
                total += i;
            }
            notify();
        }
    }
}

Edit: The answer is that the synchronization let the current thread owns the semaphore. notify() documentation explains that.

like image 616
user84592 Avatar asked Mar 18 '23 21:03

user84592


1 Answers

You should only use final objects as monitors. It will save you some nasty bugs.

If your monitor is not made final there is always the chance that it will be set to reference a new object and in such case code that appears to be synchronized will in fact run in parallel. Read here for more.

Here's how it's done:

A. Consumer:

static final Object monitor = new Object(); //<---------------
static volatile boolean completed = false;


public class ThreadA {
   public static void main(String[] args){
     ThreadB b = new ThreadB();
     b.start();

     synchronized(monitor) {
          while (!completed) { 
               monitor.wait();
          }
     }

     // when here: producer had completed <-----------------
  }
}

B. Producer:

class ThreadB extends Thread{
    int total;
    @Override
    public void run(){
        for(int i=0; i<100 ; i++) { //<------------ no need to synchronize 
             total += i;
        }

        completed = true; <--------- mark producer as completed

        synchronized(monitor) {
            monitor.notify(); 
        }
    }
}
like image 147
Gilad Haimov Avatar answered Mar 28 '23 17:03

Gilad Haimov