0

Assuming I have two different objects of same class, do they will able to execute the same synchronized method at the same time because the lock is on the object ant not on the method.

Example:

MyCLass cc= new MyCLass();
MyCLass cc1= new MyCLass();

Now create two thread t1 --- it will call cc.meth t2--it will call cc1.meth

// in this case t1 thread get lock on object cc and t2 thread get lock  on object cc1.. it will work
synchronized meth(){
}

is it correct?

elirandav
  • 1,913
  • 19
  • 27
Nikhil
  • 1
  • 2
  • Please provide a code example of what you are trying to accomplish. Your question is not properly formatted and the question is too vague. – Fabien Jul 15 '17 at 07:17
  • public static void main(String args[]){ MyClass pc = new MyClass(); MyClass pc1 = new MyClass(); Thread t1 =new Thread(() -> { pc.asfd(); } }); Thread t2 = new Thread(() -> { pc1.asfd(); }); t1.start(); t2.start(); } class MyClass{ pubic synchronized void asdf(){ // some statements } if there are two different objects of same class they can execute same synchronized method at the same time?? – Nikhil Jul 15 '17 at 13:57

3 Answers3

1

I think your question is answered here https://docs.oracle.com/javase/tutorial/essential/concurrency/syncmeth.html, that tell that just one instance of the same class is locked while executing a synchronized method, obviously even if executed by a thread.

ugo
  • 284
  • 1
  • 2
  • 10
  • so two different objects of the same class can they execute same synchronized method at the same time?? because thread need lock on the object to execute synchronised method in this case, for example, two thread t1 and t2 and two objects o1 and o2 of the same class. t1 get the lock on o1 and t2 get the lock on o2. so now both thread can execute same synchronized method at the same time because both threads have the lock on the different object . is it correct ??? I hope i am clear now – Nikhil Jul 15 '17 at 14:04
  • @Nikhil you used different terms, but I think that you mean the same thing, so it's correct. Keep in mind that MyClass o1 = new MyClass(); and MyClass o2 = new MyClass(); are 2 different object and 2 different instances of the same class, while MyClass o1 = new MyClass(); and MyClass o2 = o1; o1 and o2 are the same instance so calling a syncronized method of one lock the other too. – ugo Jul 15 '17 at 16:45
0

synchronized implemented by monitorenter. You can see it in your byte code. monitorenter use the object monitor - the monitor of the instance of the class (not the class itself). So it is the expected behavior. If two threads try to execute synchronized methods of two different instances at the same time, both should not be blocked.

Actually it is better to avoid synchronized if the objects are not shared because synchronized is not good for performance. You should start thinking about synchronized only when you know that the object will be shared by more than one thread, which is not your case.

EDIT: More simple explanation is that this code:

public synchronized void meth() {
    ...
}

equivalent to:

public void meth() {
    synchronized (this){
    ...
    }
}
elirandav
  • 1,913
  • 19
  • 27
  • but the synchronized method would be same in this case two thread and two instances of the same class. will it allow to execute synchronized method by two thread as both threads have the lock on objects as per definition if the thread has locked it can enter in synchronized method – Nikhil Jul 15 '17 at 14:18
  • Yes. The method is the same, but every thread holds **different instance**, and `synchronized` **locks** using a monitor associated to the **instance**. – elirandav Jul 15 '17 at 14:41
  • Thank you for the reply. That means a synchronized method also can execute by more than one thread at the same time. – Nikhil Jul 15 '17 at 14:59
  • Yes. If these threads holds different instances. Actually it is better to **avoid `synchronized`** if the objects are **not shared** because `synchronized` is not good for performance. You should start thinking about `synchronized` only when you know that the object will be shared by more than one thread. – elirandav Jul 15 '17 at 15:22
  • Agreed. is it better to use thread local variable which also ensures thread safety and each thread will have own copy of variable and variable will not share among threads. will it be the more better approach – Nikhil Jul 15 '17 at 15:31
  • I am not sure if you are asking a question... it looks like you forget the question mark :) and about deciding the approach, it is depends on the use case. – elirandav Jul 15 '17 at 15:37
0

You are right. Synchronized methods lock their instance, not the class nor the method (for synchronized static methods, see below...).

So, on a given instance, only one thread can be inside any of its synchronized methods, but that does not block threads working with other instances of the same class.

Synchronized static methods lock the class (they don't have a this instance), so of all threads only one at a time can be executing inside a synchronized static method of the given class.

And if you need some other locking scheme, you can use a synchronized(someObject) { ... } block, which synchronizes on someObject, and then you are free to select the object that represents the mutual-exclusion group.

So, a synchronized method A.b() is equivalent to synchronized(this) {...} or (in the static case) synchronized(A.class) {...}.

Ralf Kleberhoff
  • 6,990
  • 1
  • 13
  • 7