Reputation: 199
I have simple code:
public class testing {
private static Object objToSync = new Object();
public static void main(String[] args) {
String obj1 = null;
synchronized(objToSync){
System.out.println("something one");
doSomething();
System.out.println("something three ");
}
doSomething();
}
private static void doSomething() {
synchronized(objToSync){
System.out.println("something two");
}
}
I have read several things but still getting confused with this one. Why does the doSomething in the main gets called? Is it not suppose to wait till the synchronized object gets unlocked? Sorry if I am sounding stupid, i am just confused.
Upvotes: 1
Views: 7524
Reputation: 33544
Locks are reentrants for the same thread. That means a thread which has gained the lock of an object can access this and any other synchronized methods (or atomic statements, like here in your example) of the object. This thread will not need to gain the lock again, once it has gotten it.
Upvotes: 2
Reputation: 1075587
Is it not suppose to wait till the synchronized object gets unlocked?
The lock is held by the thread, so the fact that you're synchronizing on it twice (in the case of the first call to doSomething
in main
) doesn't matter, it's on the same thread. If another thread then tried to enter a synchronized
block on objToSync
, that other thread would wait until this thread released all of its locks.
Your code will do this:
main
objToSync
objectdoSomething
objToSync
objToSync
doSomething
objToSync
doSomething
objToSync
doSomething
main
Here's an example using two threads:
public class SyncExample {
private static Object objToSync = new Object();
public static final void main(String[] args) {
Thread second;
System.out.println("Main thread acquiring lock");
synchronized (objToSync) {
System.out.println("Main thread has lock, spawning second thread");
second = new Thread(new MyRunnable());
second.start();
System.out.println("Main thread has started second thread, sleeping a moment");
try {
Thread.currentThread().sleep(250);
}
catch (Exception e) {
}
System.out.println("Main thread releasing lock");
}
System.out.println("Main thread sleeping again");
try {
Thread.currentThread().sleep(250);
}
catch (Exception e) {
}
System.out.println("Main thread waiting for second thread to complete");
try {
second.join();
}
catch (Exception e) {
}
System.out.println("Main thread exiting");
}
static class MyRunnable implements Runnable {
public void run() {
System.out.println("Second thread running, acquiring lock");
synchronized (objToSync) {
System.out.println("Second thread has lock, sleeping a moment");
try {
Thread.currentThread().sleep(250);
}
catch (Exception e) {
}
System.out.println("Second thread releasing lock");
}
System.out.println("Second thread is done");
}
}
}
Output:
Main thread acquiring lock Main thread has lock, spawning second thread Main thread has started second thread, sleeping a moment Second thread running, acquiring lock Main thread releasing lock Main thread sleeping again Second thread has lock, sleeping a moment Main thread waiting for second thread to complete Second thread releasing lock Second thread is done Main thread exiting
Upvotes: 11
Reputation: 124275
Locks are reentrant
so if some thread posses lock it can enter other synchronized blocks based on that lock. In your case you have only one thread (main) and he is doing something like this
synchronized(objToSync){
System.out.println("something one");
synchronized(objToSync){
System.out.println("something two");
}
System.out.println("something three");
}
Upvotes: 5
Reputation: 9182
Thats because your program has only 1 thread- the main thread.
Upvotes: 1