学习synchronized可重入锁在以下三种情况的不同表现。
1、正常wait()和notify情况
/**
* 使用Object类中得wait()方法让线程等待,使用Object类中得notify()方法唤醒线程
*/
public class WaitNotifyLock {
public static void main(String[] args) {
Object object = new Object();
new Thread(() -> {
synchronized (object){
System.out.println(Thread.currentThread().getName() + "\t" + "waitThread come in");
try {
object.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "\t" + "waitThread out");
}
}, "waitThread").start();
new Thread(() -> {
synchronized(object){
object.notify();
System.out.println(Thread.currentThread().getName() + "\t" + "notifyThread notify");
}
}, "notifyThread").start();
}
}
执行结果:
waitThread waitThread come in
notifyThread notifyThread notify
waitThread waitThread out
2、去掉synchronized同步代码块
/**
* 使用Object类中得wait()方法让线程等待,使用Object类中得notify()方法唤醒线程
*/
public class WaitNotifyLock {
public static void main(String[] args) {
Object object = new Object();
new Thread(() -> {
// synchronized (object){
System.out.println(Thread.currentThread().getName() + "\t" + "waitThread come in");
try {
object.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "\t" + "waitThread out");
// }
}, "waitThread").start();
new Thread(() -> {
// synchronized(object){
object.notify();
System.out.println(Thread.currentThread().getName() + "\t" + "notifyThread notify");
// }
}, "notifyThread").start();
}
}
当没有同步代码块时,抛出异常
Exception in thread "notifyThread" Exception in thread "waitThread" java.lang.IllegalMonitorStateException
at java.lang.Object.wait(Native Method)
at java.lang.Object.wait(Object.java:502)
at com.liuyc.lock.WaitNotifyLock.lambda$main$0(WaitNotifyLock.java:15)
at java.lang.Thread.run(Thread.java:745)
java.lang.IllegalMonitorStateException
at java.lang.Object.notify(Native Method)
at com.liuyc.lock.WaitNotifyLock.lambda$main$1(WaitNotifyLock.java:25)
at java.lang.Thread.run(Thread.java:745)
waitThread waitThread come in
3、尝试先执行notify后执行wait方法来唤醒线程
import java.util.concurrent.TimeUnit;
/**
* 使用Object类中得wait()方法让线程等待,使用Object类中得notify()方法唤醒线程
*/
public class WaitNotifyLock {
public static void main(String[] args) {
Object object = new Object();
new Thread(() -> {
try {TimeUnit.SECONDS.sleep(3);} catch (InterruptedException e) {e.printStackTrace();} // 延迟3秒
synchronized (object){
System.out.println(Thread.currentThread().getName() + "\t" + "waitThread come in");
try {
object.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "\t" + "waitThread out");
}
}, "waitThread").start();
new Thread(() -> {
synchronized(object){
object.notify();
System.out.println(Thread.currentThread().getName() + "\t" + "notifyThread notify");
}
}, "notifyThread").start();
}
}
执行结果:
notifyThread notifyThread notify
waitThread waitThread come in
通过执行结果可以看出,notify方法并未唤醒阻塞线程。
总结:wait和notify方法必须要在同步块或者方法里面且成对出现使用,先wait后nofity才行