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()?
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()?
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.
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.
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.
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.
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.