个人随笔
目录
线程的阻塞和唤醒之wait()和notify()
2022-12-25 19:01:16

Object对象的wait()方法和notify()方法通常用于线程之间的阻塞和唤醒,但是这两个方法必须在同步代码块synchronized里面,否则会报错,也不能先执行notify()方法后执行wait()方法,这样wait()方法执行完后就一直阻塞了,下面是例子。

1、正常使用的代码

  1. public class WaitAndNotify {
  2. public static void main(String[] args) {
  3. Object lock = new Object();
  4. //wait()和notify()的使用必须要有锁,没有锁的话会报错
  5. new Thread(()->{
  6. synchronized (lock) {
  7. System.out.println(Thread.currentThread().getName()+"进来啦,然后被wait阻塞");
  8. try {
  9. lock.wait();
  10. } catch (InterruptedException e) {
  11. e.printStackTrace();
  12. }
  13. System.out.println(Thread.currentThread().getName()+"被唤醒啦");
  14. }
  15. },"t1").start();
  16. try {
  17. Thread.sleep(2000);
  18. } catch (InterruptedException e) {
  19. e.printStackTrace();
  20. }
  21. new Thread(()->{
  22. synchronized (lock) {
  23. System.out.println(Thread.currentThread().getName()+"notify唤醒了t1");
  24. lock.notify();
  25. }
  26. },"t2").start();
  27. }
  28. }

输出结果

  1. t1进来啦,然后被wait阻塞
  2. t2notify唤醒了t1
  3. t1被唤醒啦

跟预想的一致。

2、wait()和notify()的使用必须要有锁,没有锁的话会报错

  1. public class WaitAndNotify {
  2. public static void main(String[] args) {
  3. Object lock = new Object();
  4. //wait()和notify()的使用必须要有锁,没有锁的话会报错
  5. new Thread(()->{
  6. //synchronized (lock) {
  7. System.out.println(Thread.currentThread().getName()+"进来啦,然后被wait阻塞");
  8. try {
  9. lock.wait();
  10. } catch (InterruptedException e) {
  11. e.printStackTrace();
  12. }
  13. System.out.println(Thread.currentThread().getName()+"被唤醒啦");
  14. //}
  15. },"t1").start();
  16. try {
  17. Thread.sleep(2000);
  18. } catch (InterruptedException e) {
  19. e.printStackTrace();
  20. }
  21. new Thread(()->{
  22. //synchronized (lock) {
  23. System.out.println(Thread.currentThread().getName()+"notify唤醒了t1");
  24. lock.notify();
  25. //}
  26. },"t2").start();
  27. }
  28. }
  1. t1进来啦,然后被wait阻塞
  2. Exception in thread "t1" java.lang.IllegalMonitorStateException
  3. at java.lang.Object.wait(Native Method)
  4. at java.lang.Object.wait(Object.java:502)
  5. at mydemo.jdk.juc.wait.WaitAndNotify.lambda$0(WaitAndNotify.java:16)
  6. at mydemo.jdk.juc.wait.WaitAndNotify$$Lambda$1/989110044.run(Unknown Source)
  7. at java.lang.Thread.run(Thread.java:745)

3、如果先执行notify()后执行wait()则唤醒失败,会阻塞下去

  1. public class WaitAndNotify {
  2. public static void main(String[] args) {
  3. Object lock = new Object();
  4. //wait()和notify()的使用必须要有锁,没有锁的话会报错
  5. new Thread(()->{
  6. try {
  7. //这里休息三秒,那么就是她唤醒线程先执行才能到这里的阻塞执行了
  8. Thread.sleep(3000);
  9. } catch (InterruptedException e1) {
  10. // TODO Auto-generated catch block
  11. e1.printStackTrace();
  12. }
  13. synchronized (lock) {
  14. System.out.println(Thread.currentThread().getName()+"进来啦,然后被wait阻塞");
  15. try {
  16. lock.wait();
  17. } catch (InterruptedException e) {
  18. e.printStackTrace();
  19. }
  20. System.out.println(Thread.currentThread().getName()+"被唤醒啦");
  21. }
  22. },"t1").start();
  23. try {
  24. Thread.sleep(2000);
  25. } catch (InterruptedException e) {
  26. e.printStackTrace();
  27. }
  28. new Thread(()->{
  29. synchronized (lock) {
  30. System.out.println(Thread.currentThread().getName()+"notify唤醒了t1");
  31. lock.notify();
  32. }
  33. },"t2").start();
  34. }
  35. }
  1. t2notify唤醒了t1
  2. t1进来啦,然后被wait阻塞
 109

啊!这个可能是世界上最丑的留言输入框功能~


当然,也是最丑的留言列表

有疑问发邮件到 : suibibk@qq.com 侵权立删
Copyright : 个人随笔   备案号 : 粤ICP备18099399号-2