有个synchronized相关代码一直没看懂:
public class test {
public static void main(String[] args) throws InterruptedException {
MyThreadd t1 = new MyThreadd("t1");
synchronized (t1) {
System.out.println(Thread.currentThread().getName()+" start t1");
t1.start();//依然是主线程代码!!也就是main线程,不要认为是t1就不是主线程了
System.out.println(Thread.currentThread().getName()+" wait");
t1.wait();//依然是主线程代码!!也就是main线程,不要认为是t1就不是主线程了
System.out.println(Thread.currentThread().getName()+" waked up");
}
}
}
class MyThreadd extends Thread{
public MyThreadd(String name) {
// TODO Auto-generated constructor stub
super(name);
}
public void run(){
synchronized (this) {
System.out.println(Thread.currentThread().getName()+" notify a thread");
notify();
}
while(true);
}
}
后来发现是自己混淆了线程的概念,这里t1.start和t1.wait都是在主线程(main线程)中执行的,不是在t1线程。
其中,t1.start启动了t1线程,t1线程执行的是run方法;
t1.wait使得main线程阻塞,释放锁,从而使得t1线程中run方法里被synchronized标记的部分得到锁,t1线程继续执行,唤醒main线程。
注:在t1.wait前让主线程sleep3秒,可以明显看到t1打印出来“进入T1 is Running”,接着阻塞了,直到3秒后主线程被wait。
jdk官方文档中这样解释:
wait():
public final void wait() throws InterruptedException
在其他线程调用此对象的 notify() 方法或 notifyAll() 方法前,导致当前线程等待。换句话说,此方法的行为就好像它仅执行 wait(0) 调用一样。
当前线程必须拥有此对象监视器。该线程发布对此监视器的所有权并等待,直到其他线程通过调用 notify 方法,或 notifyAll 方法通知在此对象的监视器上等待的线程醒来。然后该线程将等到重新获得对监视器的所有权后才能继续执行。