views:

198

answers:

5
class A {
    private synchronized f() {
        ...
        ...
    }

    private synchronized g() {
        ...
        ...
    }
}

If thread T1 is running f(), can thread t2 run g() at the same point of time, while T1 is still running f()?

+15  A: 

Not on the same instance of A. The instance itself is the lock so two execute the two methods at the same time with two threads you would need two instances of A.

willcodejavaforfood
really? that seems pointless. have you a link to any spec that says this?
James
@James - It's all about protecting shared state. If multiple threads could access methods in one class at the same time the state would not be protected at all, which would be pointless. One thread at a time boys.
willcodejavaforfood
@James, you might want to read http://www.artima.com/underthehood/threadP.html . I'll quote the following - "When the JVM resolves the symbolic reference to a method, it determines whether the method is synchronized. If it is, the JVM acquires a lock before invoking the method. For an instance method, the JVM acquires the lock associated with the object upon which the method is being invoked. For a class method, it acquires the lock associated with the class to which the method belongs."
Vineet Reynolds
Wow, Thanks for your responses. So it seems marking a method as 'synchronized' is brutal, it's better to synchronize on class members?
James
@James - This is the easiest way to ensure that your shared state is protected. Yes it could be a performance bottle neck if you have many threads competing for this class. I recommend reading the book 'Java Concurrency in Practice' which is a good start.
willcodejavaforfood
@James, the lock should be placed on the relevant object with the smallest footprint. The larger the lock, the larger is the tendency for other threads to be blocked.
Vineet Reynolds
+2  A: 

Yes, if T1 and T2 are executing f and g respectively on different instances of A.

If both threads are executing a method on the same instance of A, only one will be able to execute a method at a time. If T1 runs first, it will acquire the lock on the instance of A, and execute method f. Thread T2 will be unable to execute method g until after T1 has finished executing f. Or the opposite could happen: T2 could run g first, and T1 won't be able to run f until after T2 has finished.

Richard Fearn
+2  A: 

In general, two threads can run two methods at the same point in time; however, in your example only one thread might be running f() or g() at any given moment.

Using the synchronized keyword changes thread interactions. Every java object has a lock, an item that only one thread can hold at any given time. Synchronized is a command that directs the threads to acquire the lock before execution of a method and release it afterward. The lock is held during the entire execution of the method.

In your example, only one thread will be executing f() or g() at any given time because the "other" thread will be waiting its turn to grab the lock.

When you have two objects of the same class, you have two locks. That means you could get two threads to run f() and g() simultaneously with the synchronized keywords intact, as the threads will be grabbing locks on different objects. You just can't get threads to execute simultaneously on the same object without removing the synchronized keyword.

Edwin Buck
+4  A: 

No. One call will block until the other completes. The reason for this is that the synchronized keyword on a method expands to synchronize on the current instance of the object. To be more specific, consider this code:

private void synchronized f() {
  ...
}

The above code is identical in functionality to the following code:

private void f() {
  synchronized (this) {
    ...
  }
}

So if you want two methods in an object to be synchronized only to each other, you should create two lock objects. Each method should wrap all of its code inside a synchronized (object) block, one object for each method.

Erick Robertson
A: 

for the interest of technicality and pedanticality, yes, both methods could be entered at the same time. one is blocked on synchronized (this), non the less, the method is entered and running, it's first statement is being executed, and the first byte code instruction is carried out.

irreputable