-1

I was going through multi-Threading concepts.

 public class Foo{

    public void testMethod1(){

      synchronized(foo.class){

      // only one thread can access this block at a time
      }

    }

   // or i can use the below method

    public void testMethod2(){

      synchronized(SomeClass.class){

      // only one thread can access this block at a time

      }
    }

}

I will use either testMethod1 or testMethod2 in my code.

As you can see i am using synchronized on the Foo.class in testMethod1() , and SomeClass.class in testMethod2().

If anyone method i am using it is giving same result in multiple thread access. I want to know the difference between the usages, when I have to use same class for synchronized block and some other class for synchronized block.

Or there is any difference between the above two methods?

Aslam a
  • 750
  • 10
  • 19
  • 1
    There is no any difference between of them. – Bahramdun Adil Jan 20 '17 at 07:22
  • 2
    Yes, there is a difference. They are not synchronizing on the same object, so they are not mutually exclusive, meaning that one thread can execute code inside `synchronized(foo.class)` block, while another thread can execute code inside `synchronized(SomeClass.class)` class, **at the same time**. – Andreas Jan 20 '17 at 07:26
  • 1
    My findings. Any AnyClass.class or AnyClass.getClass() will return a class object which is unique/singleTon. Hence synchronized(AnyClass.class) will have lock to that reference hence only one thread can access that block. Also we can use private static final Object lock = new Object(); to make a lock. So we can use AnyClass.class in synchronized block. – Aslam a Jan 20 '17 at 09:31

1 Answers1

1

We synchronize on objects, not on classes. And that's what you do too: you synchronize on two different instances of Class. If we rewrite a bit, it becomes clearer:

public class Foo {

    // the locks for the synchronized methods
    private Class<Foo> lock1 = Foo.class;
    private Class<SomeClass> lock2 = SomeClass.class;

    public void testMethod1() {
        synchronized (lock1) {
            // only one thread can access this block at a time
        }
    }

    public void testMethod2() {
        synchronized (lock2) {
            // only one thread can access this block at a time
        }
    }
}

We have two locks, both methods can be executed in parallel but each method only by one thread at a time.

If we would use the same lock on both methods, then the methods couldn't be executed in parallel anymore (if one thread has entered method 1, then method 2 would be locked too)

Hope it helps!

Raman Sahasi
  • 30,180
  • 9
  • 58
  • 71
Andreas Dolk
  • 113,398
  • 19
  • 180
  • 268
  • Hi Andeas . I have edited the question. Actually my quesition synchronized(foo.class) and synchronized(SomeClass.class) , when should i use the same class for synchronized block and when some other class. As I know synchronized block will do class level lock and only one thread can access that block. So can i use any class to do class level lock. – Aslam a Jan 20 '17 at 07:36
  • 1
    @Andreas_D What's special about using class references as a lock? If we use `private final Object lock1 = new Object();` and `private final Object lock2 = new Object();`, that will also have the same effect. Isn't it? – Raman Sahasi Jan 20 '17 at 07:43
  • Please read my answer carefully. The lock is not a *class* but an *object*. You don't have to use class instances, a `private Object lock3 = new Object()` would do the same. If you want to lock single methods: use different locks for the methods. If you want to lock groups of methods altogether: use a single lock for multiple methods. It only depends on your use case, on the problem you want to solve with the code. – Andreas Dolk Jan 20 '17 at 07:44
  • @Aslamanwer, Maybe you don't understand that _a class is an object_. The expression `SomeClass.class` returns a refernce to a singleton, Java object, and the class of that object is `java.lang.Class`. – Solomon Slow Jan 21 '17 at 14:36
  • Be careful. Please don't mix concepts. In OOP, an `object` is an instance of a `class`. But here we talk about Java: Each java type (except the primitive types) has an associated instance of the `java.lang.Class` type. `Singleton` is only true in the scope of a single classloader. If you have to deal with more classloaders, then a single Java type can be represented by many `Class` instances in the same java virtual machine. – Andreas Dolk Jan 21 '17 at 15:22