synchronized block not locking the object reference

房东的猫 提交于 2019-12-02 10:58:00

问题


class Demo
{
    void demo()
    {
        System.out.println("Inside demo of "+Thread.currentThread().getName());
        try
        {
            Thread.sleep(1000000);
        }
        catch(InterruptedException exc)
        {
            System.out.println(Thread.currentThread().getName()+" interrupted");
        }
    }
}

class MyThread1 implements Runnable
{
    Thread thread;
    Demo d;

    MyThread1(String name, Demo ob)
    {
        d = ob;
        thread = new Thread(this, name);
        thread.start();
    }

    @Override
    public void run()
    {
        System.out.println(thread.getName()+" starting");

        synchronized(d)
        {
            d.demo();
        }

        System.out.println(thread.getName()+" ending");
    }
}

class MyThread2 implements Runnable
{
    Thread thread;
    Demo d;

    MyThread2(String name, Demo ob)
    {
        d = ob;
        thread = new Thread(this, name);
        thread.start();
    }

    @Override
    public void run()
    { 
       System.out.println(thread.getName()+" starting");

       d.demo();

       System.out.println(thread.getName()+" ending");
    }
}

class TimePass
{
    public static void main(String args[])
    {
        Demo d = new Demo();

        MyThread1 mt1 = new MyThread1("Thread 1", d);
        MyThread2 mt2 = new MyThread2("Thread 2", d);
    }
}

The output is

Thread 1 starting

Inside demo of Thread 1

Thread 2 starting

Inside demo of Thread 2

Due to Thread.sleep(1000000), the execution is not yet ended.

I have passed the same instance of class Demo to both the constructors of classes MyThread1 and MyThread2.

Demo d = new Demo();
MyThread1 mt1 = new MyThread1("Thread 1", d);
MyThread2 mt2 = new MyThread2("Thread 2", d);

The call to d.demo in MyThread1 is in a synchronized block.
The call to d.demo in MyThread2 is not in a synchronized block.

So, when MyThread1 is executing, due to the synchronized block, the monitor of d should be locked, resulting in denial of access to d.demo() by the MyThread2.

But this is not happening.

The expected output is

Thread 1 starting
Inside demo of Thread1
Thread 2 starting

(The output is before Thread.sleep(1000000) is finished.)

So, my basic question is: How MyThread2.d.demo() is executing successfully even if MyThread1.d.demo() is not yet finished the synchronized block?


回答1:


So, when MyThread1 is executing, due to the synchronized block, the monitor of d should be locked, resulting in denial of access to d.demo() by the MyThread2.

That would only happen if MyThread2 also had a synchronized block. When one thread is synchronized on an object, other threads will be blocked if they also try to synchronize on that same object. If they don't synchronize, they won't be. There's nothing that stops access to an object from threads that don't synchronize on it.

Synchronization is a cooperative mechanism. It only works when all threads work together.




回答2:


The synchronization only occurs in Thread1. Since Thread2 does not synchronize on d, it is allowed to invoke demo() while Thread1 holds the lock.

You seem to be misunderstanding the use of synchronized. Synchronization only occurs with other threads trying to enter a synchronized block of the common object.




回答3:


Synchronization is a collaborative effort. Each party states that when another party is in a critical section, they won't be.

You've only synchronized access to the demo method of the Demo instance in one thread

synchronized(d)
{
    d.demo();
} 

The other is accessing it directly

d.demo();

They've broken these collaboration rules so you can't assume anything.

This is explained in the JLS

Acquiring the lock associated with an object does not in itself prevent other threads from accessing fields of the object or invoking un-synchronized methods on the object. Other threads can also use synchronized methods or the synchronized statement in a conventional manner to achieve mutual exclusion.



来源:https://stackoverflow.com/questions/31059728/synchronized-block-not-locking-the-object-reference

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!