Plz explain this program..

Here in this program there is a static lock, which is a lock on a class, so at a time only lock1 or lock2 can be attained. So i am not understanding the output:

public class MyClass extends Thread{
      static Object lock1 = new Object();
      static Object lock2 = new Object();

      static volatile int i1, i2, j1, j2, k1, k2;

      public void run(){
            while(true){
                  doIt();
                  check();
            }
      }
      
      void doIt(){
            synchronized(lock1){ System.out.print(Thread.currentThread().getName()); i1++; }
            j1++;
            synchronized(lock2){ System.out.print(Thread.currentThread().getName()); k1++; k2++; }
            j2++;
            synchronized(lock1){ System.out.print(Thread.currentThread().getName()); i2++; }
      }

      void check(){
            try{
                  Thread.sleep(100);
                  if(i1 != i2) System.out.print("i1" + i1 + "i2" + i2);
                  else System.out.print("not i" + i1 + "not i2" + i2);
            }catch(InterruptedException e){}
            
            try{
                  Thread.sleep(100);
                  if(j1 != j2) System.out.print("j1" + j1 + "j2" + j2);
                  else System.out.print("not j1" + j1 + "not j2" + j2);
            }catch(InterruptedException e){}
                        try{
                  Thread.sleep(100);
                  if(k1 != k2) System.out.print("k1" + k1 + "k2" + k2);
                  else System.out.print("not k1" + k1 + "not k2" + k2);
            }catch(InterruptedException e){}
            
      }

      public static void main(String... args){
            new Thread(new MyClass(),"First Thread").start();
            //new Thread(new MyClass(), "Second Thread").start();      
      }
}
      
LVL 2
SunScreenCertAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Ajay-SinghCommented:
> so at a time only lock1 or lock2 can be attained.

This is *not* true. Since lock1, and lock2 are two different objects, at
any point of time - both can be locked.
0
SunScreenCertAuthor Commented:
but what i know that lock1 and lock2 being static acquires lock on the class, so the same class lock cannot be obtained twice even if they are different objects
0
Ajay-SinghCommented:
You have,
   static Object lock1 = new Object();

This means that lock1 object is class-level variable initialized to an
instance of Object. The same is true with lock2. Now, lock1 and lock2
variables are pointing to 2 different objects and hence they can be
locked simultaneously.

If you change your code to,
   static Object lock1 = MyClass.class;
   static Object lock2 = MyClass.class;

or
   static Object lock1 = new Object();
   static Object lock2 = lock1;

You can't lock both object concurrently. Now, they point to same instance.
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
JavaScript Best Practices

Save hours in development time and avoid common mistakes by learning the best practices to use for JavaScript.

SunScreenCertAuthor Commented:
ok great explanation, so now tell me that when lock1 and lock2 acquire lock, they acquire lock on different objects, not on Class object. So they run simultaneously. But  since there are two threads running so can they swap acquiring locks.

Sorry for all the silly questions. I am really not able to understand the flow or output. I even changed things this way to understand each output

public class MyClass extends Thread{
      static Object lock1 = new Object();
      static Object lock2 = new Object();

      static volatile int i1, i2, j1, j2, k1, k2;

      public void run(){
            while(i1 < 1){
                  doIt();
                  check();
            }
      }
      
      void doIt(){
            synchronized(lock1){ System.out.println(Thread.currentThread().getName()); i1++; System.out.println(i1); }
            j1++;
            synchronized(lock2){ System.out.println(Thread.currentThread().getName()); k1++; k2++;  System.out.println(k1); System.out.println(k2); }
            j2++;
            synchronized(lock1){ System.out.println(Thread.currentThread().getName()); i2++; System.out.println(i2); }
      }

      void check(){
            try{
                  Thread.sleep(100);
                  if(i1 != i2) System.out.print("i1 " + i1 + "i2 " + i2);
                  else System.out.print("not i1 " + i1 + "not i2 " + i2);
            }catch(InterruptedException e){}
            
            try{
                  Thread.sleep(100);
                  if(j1 != j2) System.out.print("j1 " + j1 + "j2 " + j2);
                  else System.out.print("not j1 " + j1 + "not j2 " + j2);
            }catch(InterruptedException e){}
                        try{
                  Thread.sleep(100);
                  if(k1 != k2) System.out.print("k1 " + k1 + "k2 " + k2);
                  else System.out.print("not k1 " + k1 + "not k2 " + k2);
            }catch(InterruptedException e){}
            
      }

      public static void main(String... args){
            new Thread(new MyClass(),"First Thread").start();
            //new Thread(new MyClass(), "Second Thread").start();      
      }
}
      
0
SunScreenCertAuthor Commented:
ok i made this simple program to understand it
import java.util.*;
class MyCurrentDate implements Runnable{
      Date d = new Date();
      public void run(){
            synchronized(MyCurrentDate.class){
      for(int i = 0; i < 2; i++){
            System.out.println(Thread.currentThread() + "  " + d);
            try{
                  Thread.sleep(10000);
            }catch(InterruptedException e){
                  e.printStackTrace();
            }
      }
      }}
      
}
class MyMain{
      public static void main(String... args){
      Thread a = new Thread(new MyCurrentDate(), "a1");
      Thread b = new Thread(new MyCurrentDate(), "b1");
      Thread c = new Thread(new MyCurrentDate(), "c1");
      a.start();
      b.start();
      c.start();
      System.out.println("entering into threadpool");
      }
}



Now since we have class lock once Thread a1 finishes execution it is only after that b1 starts..
and if we synchronize on object that is the this instance then all threads continue running.
0
Ajay-SinghCommented:
>> Now since we have class lock once Thread a1 finishes execution it is only after that b1 starts..
and if we synchronize on object that is the this instance then all threads continue running.

Since all the threads here acquire same object (which is reference to class) they will run serially.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Java

From novice to tech pro — start learning today.