5

Why is it that two synchronized blocks can't be executed simultaneously by two different threads in Java.

EDIT

public class JavaApplication4 {

    public static void main(String[] args) {
        new JavaApplication4();
    }

    public JavaApplication4() {
        Thread t1 = new Thread() {

            @Override
            public void run() {
                if (Thread.currentThread().getName().equals("Thread-1")) {
                    test(Thread.currentThread().getName());
                } else {
                    test1(Thread.currentThread().getName());
                }
            }
        };
        Thread t2 = new Thread(t1);
        t2.start();
        t1.start();

    }

    public synchronized void test(String msg) {
        for (int i = 0; i < 10; i++) {
            try {
                Thread.sleep(100);
            } catch (InterruptedException ex) {
            }
            System.out.println(msg);
        }
    }

    public synchronized void test1(String msg) {
        for (int i = 0; i < 10; i++) {
            try {
                Thread.sleep(100);
            } catch (InterruptedException ex) {
            }
            System.out.println(msg + " from test1");
        }
    }
}
3
  • 4
    If they're synchronized on different objects, they can. If they are synchronized on the same object, simultaneous execution would kind of defeat the purpose. Commented Aug 10, 2012 at 11:46
  • I suspect there is a deeper concern you have. Can you rephrase your question? Commented Aug 10, 2012 at 11:50
  • @Keppil pls check the EDIT section Commented Aug 10, 2012 at 11:51

4 Answers 4

11

Your statement is false. Any number of synchronized blocks can execute in parallel as long as they don't contend for the same lock.

But if your question is about blocks contending for the same lock, then it is wrong to ask "why is it so" because that is the purpose of the whole concept. Programmers need a mutual exclusion mechanism and they get it from Java through synchronized.

Finally, you may be asking "Why would we ever need to mutually exclude code segments from executing in parallel". The answer to that would be that there are many data structures that only make sense when they are organized in a certain way and when a thread updates the structure, it necessarily does it part by part, so the structure is in a "broken" state while it's doing the update. If another thread were to come along at that point and try to read the structure, or even worse, update it on its own, the whole thing would fall apart.

EDIT

I saw your example and your comments and now it's obvious what is troubling you: the semantics of the synchronized modifier of a method. That means that the method will contend for a lock on this's monitor. All synchronized methods of the same object will contend for the same lock.

Sign up to request clarification or add additional context in comments.

2 Comments

That piece of code is quite a terrible nightmare. It checks for thread names that it didn't set explicitly and, far worse, uses one thread instance as a Runnable of the other thread. I wouldn't dare predict what kind of consequences that can have. Anyway, I ran it and it did the most obvious thing: two methods were mutually excluded.
that was just a little dummy terrible code. but my question is why is t mutually exclusive when I don't find anything wrong in it. Two different threads are accessing two different synchronized blocks
5

That is the whole concept of synchronization, if you are taking a lock on an object (or a class), none of the other threads can access any synchronized blocks.

Example

Class A{

public void method1()
{
 synchronized(this)//Block 1 taking lock on Object
 {
  //do something
 }
}

public void method2()
{
 synchronized(this)//Block 2 taking lock on Object
 {
  //do something
 }
}
}

If one thread of an Object enters any of the synchronized blocks, all others threads of the same object will have to wait for that thread to come out of the synchronized block to enter any of the synchronized blocks. If there are N number of such blocks, only one thread of the Object can access only one block at a time. Please note my emphasis on Threads of same Object. The concept will not apply if we are dealing with threads from different objects.

Let me also add that if you are taking a lock on class, the above concept will get expanded to any object of the class. So if instead of saying synchronized(this), I would have used synchronized(A.class), code will instruct JVM, that irrespective of the Object that thread belongs to, make it wait for other thread to finish the synchronized block execution.

Edit: Please understand that when you are taking a lock (by using synchronized keyword), you are not just taking lock on one block. You are taking lock on the object. That means you are telling JVM "hey, this thread is doing some critical work which might change the state of the object (or class), so don't let any other thread do any other critical work" . Critical work, here refers to all the code in synchronized blocks which take lock on that particular Object (or class), and not only in one synchronized block.

2 Comments

but the synchronized blocks are completely independent. so why is it getting blocked.
You need to understand this- you are not taking lock on a block, you are taking a lock on the Object (or class)
0

This is not absolutely true. If you are dealing with locks on different objects then multiple threads can execute those blocks.

   synchronized(obj1){
       //your code here
   }

   synchronized(obj2){
       //your code here
   }

In above case one thread can execute first and second can execute second block , the point is here threads are working with different locks.

Your statement is correct if threads are dealing with same lock.Every object is associated with only one lock in java if one thread has acquired the lock and executing then other thread has to wait until first thread release that lock.Lock can be acquired by synchronized block or method.

Comments

0

Two Threads can execute synchronized blocks simultaneously till the point they are not locking the same object.

In case the blocks are synchronized on different object... they can execute simultaneously.

synchronized(object1){
    ...
}

synchronized(object2){
    ...
}

EDIT: Please reason the output for http://pastebin.com/tcJT009i

In your example when you are invoking synchronized methods the lock is acquired over the same object. Try creating two objects and see.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.