貌似不能唤醒指定的线程,如果想唤起指定的线程,需要用到Lock锁的Condition条件

    几个重要的概念:

    《java编程思想》第四版一书中有描述到:“线程操作的wait()、notify()、notifyAll()方法只能在同步控制方法或同步控制块内调用。如果在非同步控制方法或控制块里调用,程序能通过编译,但运行的时候,将得到 IllegalMonitorStateException 异常,并伴随着一些含糊信息,比如 ‘当前线程不是拥有者’。其实异常的含义是 调用wait()、notify()、notifyAll()的任务在调用这些方法前必须 ‘拥有’(获取)对象的锁。”


    即必须在方法上加上synchronized关键字

    wait:当线程执行wait()方法时候,会释放当前的锁,然后让出CPU,进入等待状态。后面的代码不会执行。当该线程被唤醒之后会接着后面的代码执行

    1. wait(1000) 还可以设置时间

    notify/notifyAll:

    notify随机唤醒的是其所在锁所阻塞的线程 notifyAll唤醒的是全部其所在锁所阻塞的线程

    1. package com.juc.等待唤醒;
    2. /**
    3. * 线程之间的通信问题:生产者和消费者问题! 等待唤醒,通知唤醒
    4. * 线程交替执行 A B 操作同一个变量 num = 0
    5. * A num+1
    6. * B num-1
    7. */
    8. public class A {
    9. public static void main(String[] args) {
    10. Data data = new Data();
    11. new Thread(()->{
    12. for (int i = 0; i < 10; i++) {
    13. try {
    14. data.increment();
    15. } catch (InterruptedException e) {
    16. e.printStackTrace();
    17. }
    18. }
    19. },"A").start();
    20. new Thread(()->{
    21. for (int i = 0; i < 10; i++) {
    22. try {
    23. data.decrement();
    24. } catch (InterruptedException e) {
    25. e.printStackTrace();
    26. }
    27. }
    28. },"B").start();
    29. new Thread(()->{
    30. for (int i = 0; i < 10; i++) {
    31. try {
    32. data.increment();
    33. } catch (InterruptedException e) {
    34. e.printStackTrace();
    35. }
    36. }
    37. },"C").start();
    38. new Thread(()->{
    39. for (int i = 0; i < 10; i++) {
    40. try {
    41. data.decrement();
    42. } catch (InterruptedException e) {
    43. e.printStackTrace();
    44. }
    45. }
    46. },"D").start();
    47. }
    48. }
    49. // 判断等待,业务,通知
    50. class Data{ // 数字 资源类
    51. private int number = 0;
    52. //+1
    53. public synchronized void increment() throws InterruptedException {
    54. while (number!=0){ //0
    55. // 等待
    56. this.wait();
    57. }
    58. number++;
    59. System.out.println(Thread.currentThread().getName()+"=>"+number);
    60. // 通知其他线程,我+1完毕了
    61. this.notifyAll();
    62. }
    63. //-1
    64. public synchronized void decrement() throws InterruptedException {
    65. while (number==0){ // 1
    66. // 等待
    67. this.wait();
    68. }
    69. number--;
    70. System.out.println(Thread.currentThread().getName()+"=>"+number);
    71. // 通知其他线程,我-1完毕了
    72. this.notifyAll();
    73. }
    74. }
    1. A=>1
    2. B=>0
    3. A=>1
    4. B=>0
    5. A=>1
    6. B=>0
    7. A=>1
    8. B=>0
    9. A=>1
    10. B=>0
    11. A=>1
    12. B=>0
    13. A=>1
    14. B=>0
    15. A=>1
    16. B=>0
    17. A=>1
    18. B=>0
    19. A=>1
    20. B=>0
    21. C=>1
    22. D=>0
    23. C=>1
    24. D=>0
    25. C=>1
    26. D=>0
    27. C=>1
    28. D=>0
    29. C=>1
    30. D=>0
    31. C=>1
    32. D=>0
    33. C=>1
    34. D=>0
    35. C=>1
    36. D=>0
    37. C=>1
    38. D=>0
    39. C=>1
    40. D=>0