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);
}
}
输出
线程1开始
线程1的内部演示
线程2开始
线程2的内部演示
由于Thread.sleep(1000000)
,执行尚未结束。
我已将类Demo
的相同实例传递给类MyThread1
和MyThread2
的构造函数。
Demo d = new Demo();
MyThread1 mt1 = new MyThread1("Thread 1", d);
MyThread2 mt2 = new MyThread2("Thread 2", d);
d.demo
中对MyThread1
的来电位于synchronized
区块内
d.demo
中对MyThread2
的调用在<{1}}块中不。
因此,当synchronized
执行时,由于MyThread1
阻止,synchronized
的监视器应该被锁定,导致d
拒绝访问d.demo()
{1}}。
但事实并非如此。
预期输出
MyThread2
(输出在Thread 1 starting
Inside demo of Thread1
Thread 2 starting
完成之前。)
所以,我的基本问题是:即使Thread.sleep(1000000)
尚未完成MyThread2.d.demo()
阻止,MyThread1.d.demo()
如何成功执行?
答案 0 :(得分:6)
因此,当MyThread1执行时,由于
synchronized
阻止,d
的监视器应该被锁定,导致MyThread2拒绝访问d.demo()
。
只有当MyThread2也有synchronized
块时才会发生这种情况。当一个线程在一个对象上同步时,如果其他线程也尝试在同一个对象上进行同步,则会阻塞其他线程。如果他们不同步,他们就不会。没有什么可以阻止从不同步的线程访问对象。
同步是一种合作机制。它仅在所有线程协同工作时才有效。
答案 1 :(得分:3)
synchronization
仅发生在Thread1
。由于Thread2
synchronize
上没有d
,因此在Thread1持有锁时允许调用demo()
。
您似乎误解了synchronized
的使用。仅与尝试进入公共对象的同步块的其他线程同步。
答案 2 :(得分:3)
同步是一项协作努力。每一方都声明,当另一方处于关键部分时,他们不会成为。
您只能synchronized
访问一个帖子中demo
个实例的Demo
方法
synchronized(d)
{
d.demo();
}
另一个是直接访问
d.demo();
他们已经破坏了这些协作规则,因此您无法承担任何责任。
中对此进行了解释获取与对象关联的锁定本身并不存在 阻止其他线程访问对象的字段或调用 对象上的非同步方法。其他线程也可以使用 常规中的同步方法或同步语句 实现互斥的方式。