我有以下代码。它具有两个对象,即多刺林格和 threadB 对象。当我们说同步(b)时,这是什么意思?"主"线程可以在螺纹b完成执行之前在b上锁定吗?我无法理解监视对象在同步块中的意义。
package threads;
class MultiThreadingTest
{
public static void main(String[] args)
{
ThreadB b = new ThreadB();
b.setName("Thread B");
b.start();
synchronized(b)
{
System.out.println("Current thread : "+ Thread.currentThread().getName());
try
{
System.out.println("Waiting for b to complete...");
b.wait();
}
catch (InterruptedException e)
{
e.printStackTrace();
}
System.out.println("Total = "+b.total );
}
}
}
class ThreadB extends Thread
{
int total;
public void run()
{
synchronized(this)
{
System.out.println("Current thread : "+Thread.currentThread().getName());
for(int i=0;i<100;i++)
{
total = total + i;
}
notify();
}
}
}
将其视为孩子的游戏,谁持有[任何对象]会说话的人。持有监视器对象的任何人都可以在计算术语中执行。
监视器是您要锁定的对象,在任何给定时间,只有一个线程访问每个监视器对象保护的代码。该对象本身是任意的,并且对同步没有太多的重量(尽管您必须注意重新分配变量以及null
参考)。另外,JB Nizet在同步Thread
对象上提出了一个很好的观点,因为许多内部VM方法都可以引起Bazaar,难以检测错误和僵局。
在不同的监视器上锁定不同的同步块的两个线程将执行同时,类似于两个单独的人玩/颁布"曾经持有xxx的人会说话"游戏。锁定this
只是表现出单个锁定同步而无需创建其他锁定对象的便捷方法。
在您的情况下,ThreadB b
是从ThreadB
类中指向this
的对象,这意味着只有一个线程可以一次输入任何定义的同步块。该顺序高度依赖于哪个线程首先运行,线程调度程序甚至基础系统。
监视对象的主要原因是可以实现复杂的螺纹安全机制。想象一个系统,每个同步块都是单线程访问(即,在任何时候,任何线程进入同步块都会在整个VM中保存所有其他线程,试图输入一个同步块),这不仅会导致大规模的性能放缓,还会导致它只是没有意义。如果两个不相关的应用程序模块没有共享数据并且从不交互,为什么要互相锁定?
解决方案当然是要让一个模块使用与另一个模块无关/无关的一个(或几个)监视器对象,因此两者都可以同时执行彼此独立(假设这是所需的行为)。p>要进一步澄清,您可以写:
class MultiThreadingTest{
public static void main(String[] args){
ThreadB b = new ThreadB();
b.setName("Thread B");
b.start();
synchronized(b.lock){
System.out.println("Current thread : "+ Thread.currentThread().getName());
try{
System.out.println("Waiting for b to complete...");
b.lock.wait();
}catch(InterruptedException e){
e.printStackTrace();
}
System.out.println("Total = " + b.total );
}
}
}
class ThreadB extends Thread{
public final Object lock = new Object();
int total;
public void run(){
synchronized(lock){
System.out.println("Current thread : "+Thread.currentThread().getName());
for(int i = 0; i < 100; i++){
total = total + i;
}
lock.notify();
}
}
}
to 恰好与您使用的代码相同(甚至更好,因为它可以解决与thread.join()和其他方法的冲突)。
synchronized(this)
表示,如果另一个线程在代码块内部,该代码也无法输入该代码块,而该代码也与this
引用的对象同步。
synchronized(b)
表示,如果另一个线程在代码块内,该代码也无法输入该代码,该代码也同步在b
引用的对象上。
因此,他们做了完全相同的事情。唯一的区别是用于锁定的对象。
请注意,等待,同步并在类型线程的对象上通知是一个真的很糟糕的主意。它使事物感到困惑,并会导致不必要的行为,因为其他方法(例如JOIN()也将线程用作监视器。
根据我的理解,不。运行()方法中的"此"对象和Main()方法中的" B"对象是相同的。
因此,在线程完成执行之前,"主"线程不可能获取锁。
在运行()方法中的notify()似乎在这种情况下似乎是多余的
ps:请四处寻找可能已经在论坛中提出的类似问题。他们可能有助于提供更多的理解。