Let's assume that I create 2 threads CounterRunnable and create one object of Mycounter.
In the code below, how does the synchronization work? I imagined that when I synchronize on counter, which is an object defined in the thread class, I now have 2 separate objects with two different counter objects with two different locks to each object.
I thought that I am now locking on the counter object itself not the single referenced object.
public class example {
    class CounterRunnable implements Runnable {
        private MyCounter counter;
        public CounterRunnable (MyCounter counter) {
            this.counter = counter;
        }
        public void run () {
            for (int i = 0 ; i < 1000; i++)
              synchronized(this.counter){
                counter.increment();
              }
        }
    }
    class MyCounter  {
        private int c =0;
        public synchronized void increment () {
            c++;
        }
        public int value () {return c;} 
    }
    public static void main (String [] args) throws InterruptedException {
        example ex = new example();
        MyCounter counter = ex.new MyCounter();
        Thread t1 = new Thread (ex.new CounterRunnable(counter));
        Thread t2 = new Thread (ex.new CounterRunnable(counter));
        t1.start(); t2.start();
        t1.join(); t2.join();
        System.out.println(counter.value());
    }
}
 
     
    