同步块未锁定对象引用
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);
}
}
输出为
Thread 1 starting
Inside demo of Thread 1
Thread 2 starting
Inside demo of Thread 2
由于Thread.sleep(1000000)
,执行还没有结束
我已经将 class Demo
的相同实例传递给 classes MyThread1
和 MyThread2
.
的构造函数
Demo d = new Demo();
MyThread1 mt1 = new MyThread1("Thread 1", d);
MyThread2 mt2 = new MyThread2("Thread 2", d);
MyThread1
中对 d.demo
的调用在 synchronized
块中。
在 MyThread2
中对 d.demo
的调用在 synchronized
块中是 而不是 。
因此,当MyThread1
执行时,由于synchronized
块,d
的监视器应该被锁定,导致拒绝访问d.demo()
MyThread2
。
但这并没有发生。
预期输出是
Thread 1 starting
Inside demo of Thread1
Thread 2 starting
(输出在Thread.sleep(1000000)
完成之前。)
所以,我的基本问题是:即使 MyThread1.d.demo()
尚未完成 synchronized
块,MyThread2.d.demo()
如何成功执行?
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.
只有当 MyThread2 也有一个 synchronized
块时才会发生这种情况。当一个线程在一个对象上同步时,如果其他线程也尝试在同一对象上同步,它们将被阻塞。如果他们不同步,他们就不会。没有什么可以阻止不同步的线程访问对象。
同步是一种协作机制。它只有在所有线程一起工作时才有效。
synchronization
只出现在Thread1
。由于 Thread2
在 d
上没有 synchronize
,因此允许在 Thread1 持有锁时调用 demo()
。
您似乎误解了 synchronized
的用法。同步只发生在其他线程试图进入公共对象的同步块时。
同步是一项协作工作。每一方都声明,当另一方处于关键部分时,他们不会。
您只能 synchronized
访问一个线程中 Demo
实例的 demo
方法
synchronized(d)
{
d.demo();
}
对方正在直接访问
d.demo();
他们违反了这些协作规则,因此您不能假设任何事情。
这在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.
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);
}
}
输出为
Thread 1 starting
Inside demo of Thread 1
Thread 2 starting
Inside demo of Thread 2
由于Thread.sleep(1000000)
,执行还没有结束
我已经将 class Demo
的相同实例传递给 classes MyThread1
和 MyThread2
.
Demo d = new Demo();
MyThread1 mt1 = new MyThread1("Thread 1", d);
MyThread2 mt2 = new MyThread2("Thread 2", d);
MyThread1
中对 d.demo
的调用在 synchronized
块中。
在 MyThread2
中对 d.demo
的调用在 synchronized
块中是 而不是 。
因此,当MyThread1
执行时,由于synchronized
块,d
的监视器应该被锁定,导致拒绝访问d.demo()
MyThread2
。
但这并没有发生。
预期输出是
Thread 1 starting
Inside demo of Thread1
Thread 2 starting
(输出在Thread.sleep(1000000)
完成之前。)
所以,我的基本问题是:即使 MyThread1.d.demo()
尚未完成 synchronized
块,MyThread2.d.demo()
如何成功执行?
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.
只有当 MyThread2 也有一个 synchronized
块时才会发生这种情况。当一个线程在一个对象上同步时,如果其他线程也尝试在同一对象上同步,它们将被阻塞。如果他们不同步,他们就不会。没有什么可以阻止不同步的线程访问对象。
同步是一种协作机制。它只有在所有线程一起工作时才有效。
synchronization
只出现在Thread1
。由于 Thread2
在 d
上没有 synchronize
,因此允许在 Thread1 持有锁时调用 demo()
。
您似乎误解了 synchronized
的用法。同步只发生在其他线程试图进入公共对象的同步块时。
同步是一项协作工作。每一方都声明,当另一方处于关键部分时,他们不会。
您只能 synchronized
访问一个线程中 Demo
实例的 demo
方法
synchronized(d)
{
d.demo();
}
对方正在直接访问
d.demo();
他们违反了这些协作规则,因此您不能假设任何事情。
这在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.