[英]synchronized block not locking the object reference
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 线程1开始
Inside demo of Thread 1 线程1的内部演示
Thread 2 starting 线程2开始
Inside demo of Thread 2 线程2的内部演示
Due to Thread.sleep(1000000)
, the execution is not yet ended. 由于Thread.sleep(1000000)
,执行尚未结束。
I have passed the same instance of class Demo
to both the constructors of classes MyThread1
and MyThread2
. 我已经将类Demo
的相同实例传递给类MyThread1
和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. 在MyThread1
对d.demo
的调用在synchronized
块中。
The call to d.demo
in MyThread2
is not in a synchronized
block. MyThread2
对d.demo
的调用不在 synchronized
块中。
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
. 因此,在执行MyThread1
时,由于synchronized
块,应该锁定d
的监视器,从而导致MyThread2
拒绝访问d.demo()
。
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.) (输出在Thread.sleep(1000000)
完成之前。)
So, my basic question is: How MyThread2.d.demo()
is executing successfully even if MyThread1.d.demo()
is not yet finished the synchronized
block? 所以,我的基本问题是: 如何MyThread2.d.demo()
成功执行,即使MyThread1.d.demo()
尚未完成的synchronized
块?
So, when MyThread1 is executing, due to the
synchronized
block, the monitor ofd
should be locked, resulting in denial of access tod.demo()
by the MyThread2. 因此,在执行MyThread1时,由于存在synchronized
块,因此应锁定d
的监视器,从而导致MyThread2对d.demo()
的访问被拒绝。
That would only happen if MyThread2 also had a synchronized
block. 仅当MyThread2也具有synchronized
块时,才会发生这种情况。 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. 仅当所有线程一起工作时,它才起作用。
The synchronization
only occurs in Thread1
. synchronization
仅发生在Thread1
。 Since Thread2
does not synchronize
on d
, it is allowed to invoke demo()
while Thread1 holds the lock. 由于Thread2
在d
上不synchronize
,因此可以在Thread1持有锁的同时调用demo()
。
You seem to be misunderstanding the use of synchronized
. 你似乎误会使用的synchronized
。 Synchronization only occurs with other threads trying to enter a synchronized block of the common object. 同步仅在尝试输入公共对象的同步块的其他线程中发生。
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
访问了Demo
实例的demo
方法
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 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. 其他线程也可以以常规方式使用同步方法或同步语句来实现互斥。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.