2

I'm very confused because of Java's synchronized concept.

Let's assume the below class:

class MyClass {
  public synchronized void foo() { //do something }
  public void bar() {
    synchronized(this) { //do something }
  }
  public void normal() { //do something }
}

As far as I know, the foo and bar methods work the same.

But, after thread A enters the bar method and synchronizes the instance by synchronized(this), can any thread call the normal method?

As far as I know, some threads can call the normal method regardless of calling the foo method. But I'm not sure when the bar method is called because it synchronized an instance.

Also, let's assume the below method:

class StaticMyClass {
  public static synchronized void fooStatic() { //do something }
  publi static void barStatic() {
    synchronized(StaticMyClass.class) { //do something }
  }
  public static void normalStatic() { //do something }
}

Here, there is the same question. After thread A enters the critical section, which is synchronized(StaticMyClass.class) or the fooStatic method, can any thread call normalStatic?
I think that fooStatic and normalStatic can be called independently, but barStatic and normalStatic can't. If it is wrong, why?

I appreciate your help.

Edit:
My confused point is that I am not sure that synchronized(this) is same as synchronized(myClassInstance).

MyClass my = new MyClass();
synchronized(my) {
  //do something, Any other thread can't access my.normal(), is it right?
}

class MyClass {
  public synchronized void foo() { //do something }
  public void bar() {
    synchronized(this) {
      //do something, isn't this same as above synchronized(my)?
    }
  }
  public void normal() { //do something }
}
0xCursor
  • 2,242
  • 4
  • 15
  • 33
Hyun
  • 566
  • 1
  • 3
  • 13
  • Your latest edit is unclear. You ask a question about `synchronized(myClassInstance)` which doesn't appear anywhere. You ask about locking on `my.normal()` and I have already explained that there is no locking in the `normal` method. (None. Zero. Nada. Nyet ...). Even `/* isn't this same as above synchronized(my)? */` doesn't make sense, because your code in this example doesn't show a call to `bar()`. – Stephen C Sep 02 '18 at 02:47
  • @Stephen C I apologize lack of explanation. I will edit again – Hyun Sep 02 '18 at 04:34
  • @HackingJ No problem, glad to help out. – 0xCursor Sep 02 '18 at 21:00

3 Answers3

2

As far as I know, foo and bar methods work same.

Correct. They both synchronize on this.

After thread A enter the bar method and synchronize the instance by synchronized(this), can any thread call normal method?

Yes. Correct.

As far as I know, some thread can call normal method regardless calling foo method. but I'm not sure when the bar method is called. because it synchronized a instance.

foo and bar are the same. They are both synchronizing on this. The normal method is not synchronizing on anything. Therefore it can be called at any time from anywhere and it will not blocked, either at the point of the method call, or internally.

In your terminology, the normal method is not a critical section1.


Second example with statics

Here, there is same question. after thread A enter the critical section which is synchronized(StaticMyClass.class) or fooStatic method, can any thread call normalStatic?

Yes. The fooStatic and barStatic will both synchronize on StaticMyClass.class.

I think, call fooStatic and normalStatic can be called independently, but barStatic and normalStatic can't.

Incorrect. The normalStatic is not blocked by fooStatic OR barStatic.

I'm not sure where you got the idea that normalStatic might be blocked ... but it is a normal method call and doesn't acquire any intrinsic locks, so it cannot be blocked on a lock.


Your third example is unclear. The code shows one thing, but the question asks something different / unrelated.


1 - It might get a bit confusing if (say) foo or bar called normal while holding the intrinsic lock. Then the normal code will be effectively in the critical section because the caller holds the lock. But it (normal) typically won't know this. This is why I prefer to avoid the "critical section" terminology.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
1

If you do not specify who is the monitor, with instance methods the monitor is the instance (this), and with static methods the monitor is the class (YourClass.class).

This code

public synchronized void foo() { //do something }

It is the same than this

public void foo() {
   synchronized(this) { //do something }
}

and this code

public static synchronized void fooStatic() { //do something }

is the same than this

public static void fooStatic() {
   synchronized(StaticMyClass.class) { //do something }
}

So, in both cases, foo and bar are dependant (only one thread at the same time), while normal can be called independently.

Sebastian Celestino
  • 1,388
  • 8
  • 15
1

but After thread A enter the bar method and synchronize the instance by synchronized(this), Can any thread call the normal method?

It is not possible for two invocations of synchronized methods on the same object to interleave. When one thread is executing a synchronized method for an object, all other threads that invoke synchronized methods for the same object block (suspend execution) until the first thread is done with the object.

If you are trying to call other methods which aren't synchronized, then it is possible.

after thread A enter the critical section which is synchronized(StaticMyClass.class) or fooStatic method, can any thread call normalStatic? I think, call fooStatic and normalStatic can be called independently, but barStatic and normalStatic can't. if it is wrong why?

The other methods which are not synchronized can be called independently, but when you call the barStatic() it is not possible for the other methods to be called, as you are synchronizing the entire class. other threads, have to wait until the current thread is finished executing.

Adithya
  • 241
  • 3
  • 16