关于wait和notify方法

初学线程,对于一些问题不是很明白,请看下面的示例:
public class WaitAndNotifyAndSynchronized
{
public WaitAndNotifyAndSynchronized(){
final WaitAndNotifyAndSynchronized a = this;
Thread th1 = new Thread(){
@Override
public void run(){
try
{
this.sleep(3000);

} catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
while(true){
synchronized (a){ //①
System.out.println(this);//②
a.notify();
}
}
}
};
th1.setDaemon(true);//这句也是必须的,将th1设为守护线程,保证在唤醒a以后,所有活动的线程都为守护线程,jvm能及时退出
th1.start();//③ 和a.run的顺序不可以换

this.run();

}

public static void main(String[] args)
{
    new WaitAndNotifyAndSynchronized();
}

public void run()
{
    /**
     * 这里可以换成这样,直接锁住this就行了
     */
    synchronized (this)
    {
        try
        {

            this.wait();//阻塞当前的线程并释放锁
        } catch (InterruptedException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }finally{
            System.out.println("1");//执行finally
        }
    }


}

}
1.关于①处,为什么notify和wait方法必须要同步,难道就是因为api里强制的规定吗?
2关于②处,最后的执行结果是不停的输出这里然后虚拟机退出,我的理解是notify之后此时就剩守护线程了,应该结束了,怎么还会不停的输出这里
3关于③处,为什么和a.run()不能换位置,对换执行的结果是什么都不输出,虚拟机不退出

1.notify和wait本来就是用来释放锁的,如果没有锁被释放,是会抛出异常的。
2.这个问题我不太清楚,我估计是主线程结束和jvm退出还需要执行其他的相应代码,这段时间守护线程还在执行,直到jvm关闭它。
3.如果先执行a.run()方法,调用wait方法,主线程在run方法阻塞, 那么后面这句th1.start();没有执行到,守护线程根本还没启动。