为什么主线程总是能优先拿到子线程的资源锁呢?

实在不知道如何用一句话描述清楚我的问题,不好意思了
网上看到一篇讲wait/notify的文章,把代码拷下来debug了一下(代码如下所示),发现一个奇怪的问题,主线程总是先拿到b的锁,而b这个线程运行后,始终无法拿到自身的锁,直到主线程内b.wait将b释放掉之后,很不理解,不知道有谁能解答我的疑惑,谢谢!

class ThreadA
  {
   public static void main(String[] args)
   {
   ThreadB b=new ThreadB();
   b.start();
   System.out.println("b is start....");
   synchronized(b)//括号里的b是什么意思,起什么作用?
   {
   try
   {
   System.out.println("Waiting for b to complete...");
   b.wait();//这一句是什么意思,究竟让谁 000-834 wait?
   System.out.println("Completed.Now back to main thread");
   }catch (InterruptedException e){}
   }
   System.out.println("Total is :"+b.total);
   }
  }

  class ThreadB extends Thread
  {
   int total;
   public void run()
   {
   synchronized(this) //
   {
   System.out.println("ThreadB is running..");
   for (int i=0;i<100;i++ )
   {
   total +=i;
   System.out.println("total is "+total);
   }
   notify();
   }
   }
  }

我把代码拷贝下来运行了一不, 发现运行到[code="java"]b.wait();//这一句是什么意思,究竟让谁 000-834 wait? [/code]这一行就不动了, 一直等待!在我运行过程中, 我发现总是线程b先拿到自身的锁, 所以执行顺序肯定是b线程先执行完, 然后在执行main方法中[code="java"]synchronized (b)// 括号里的b是什么意思,起什么作用?
{
try {
System.out.println("Waiting for b to complete...");
b.wait();// 这一句是什么意思,究竟让谁 000-834 wait?
System.out.println("Completed.Now back to main thread");
} catch (InterruptedException e) {
}
}[/code]的这块代码!因为[code="java"]synchronized (b)// 括号里的b是什么意思,起什么作用? [/code]和[code="java"]synchronized (this) // [/code]锁的是同一个对象, 都是b这个实例!而[code="java"]b.wait();//这一句是什么意思,究竟让谁 000-834 wait? [/code]这一名则是要当前线程处于等待状态中, 直到有其它的线程来唤醒它.但由于此时b已经执行完成, 所以不会在调用notify()方法,所以就一直等待了!我改了下你的代码, 让整个流程能正常跑完, 如下:
[code="java"]class ThreadB extends Thread {
int total;

public void run() {
    try {
        Thread.sleep(3000);
    } catch (InterruptedException e) {
    }
    synchronized (this) // <2>
    {
        System.out.println("ThreadB is running..");
        for (int i = 0; i < 100; i++) {
            total += i;
            System.out.println("total is " + total);
        }
        notify();
    }
}

}[/code], 就是加了一个sleep(3000), 这样能让main方法先拿到b的锁, 然后调用wait()方法等待并释放锁, 此时线程b拿到锁, 执行循环并调用notify()方法,唤醒主线程, 直到执行完毕.
因为notify()和wait()一定要在synchronized中执行, 所以才会出现你代码中中的synchronized.而[code="java"]b.wait();//这一句是什么意思,究竟让谁 000-834 wait? [/code]这你代码中就是为了等待线程b调用notify(); 方法!