1、线程通信模型

  • 线程间通信的模型有两种:共享内存和消息传递

2、线程通信方式一:Object.wait() 和 notify()

wait/notify注意事项

  • wait/notify必须在同步代码块或者同步函数中使用
  • wait/notify必须由同一个锁对象调用
  • wait/notify方法属于Object的方法,所以锁对象可以是任意对象
  • notify之后不是表示线程立即恢复执行,因为当初中断的地方是在同步代码块中,而此刻它已经不再持有锁,它需要再去和其他线程抢锁

    • 如果能获取锁,线程WAITING>>>RUNNABLE
    • 获取不到锁,线程WAITING>>>BLOCKED

      生产者、消费者模式

  • 生产者消费者问题(Producer-consumer problem),也称有限缓冲问题(Bounded-buffer problem),是一个多线程同步问题的经典案例。生产者生成一定量的数据放到缓冲区中,然后重复此过程;与此同时,消费者也在缓冲区消耗这些数据。生产者和消费者之间必须保持同步,要保证生产者不会在缓冲区满时放入数据,消费者也不会在缓冲区空时消耗数据。

    1. public class Main {
    2. public static void main(String[] args) throws InterruptedException {
    3. Storage storage = new Storage();
    4. Thread p1 = new Thread(new Producer(storage));
    5. Thread p2 = new Thread(new Producer(storage));
    6. Thread p3 = new Thread(new Producer(storage));
    7. Thread c1 = new Thread(new Consumer(storage));
    8. Thread c2 = new Thread(new Consumer(storage));
    9. Thread c3 = new Thread(new Consumer(storage));
    10. c1.start();
    11. c2.start();
    12. c3.start();
    13. p1.start();
    14. p2.start();
    15. p3.start();
    16. }
    17. /**
    18. * 生产者
    19. */
    20. public static class Producer extends Thread {
    21. private Storage storage;
    22. public Producer(){}
    23. public Producer(Storage storage){
    24. this.storage = storage;
    25. }
    26. @Override
    27. public void run(){
    28. while(true){
    29. try{
    30. Thread.sleep(1000);
    31. storage.produce();
    32. }catch (InterruptedException e){
    33. e.printStackTrace();
    34. }
    35. }
    36. }
    37. }
    38. /**
    39. * 消费者
    40. */
    41. public static class Consumer extends Thread {
    42. private Storage storage;
    43. public Consumer(){}
    44. public Consumer(Storage storage){
    45. this.storage = storage;
    46. }
    47. @Override
    48. public void run(){
    49. while(true){
    50. try{
    51. Thread.sleep(3000);
    52. storage.consume();
    53. }catch (InterruptedException e){
    54. e.printStackTrace();
    55. }
    56. }
    57. }
    58. }
    59. /**
    60. * 仓库类
    61. */
    62. public static class Storage extends Thread {
    63. // 仓库容量
    64. private final int MAX_SIZE = 10;
    65. // 仓库存储的载体
    66. private LinkedList<Object> list = new LinkedList<>();
    67. public void produce() {
    68. synchronized (list) {
    69. while (list.size() + 1 > MAX_SIZE) {
    70. System.out.println("【生产者" + Thread.currentThread().getName()
    71. + "】仓库已满");
    72. try {
    73. list.wait();
    74. } catch (InterruptedException e) {
    75. e.printStackTrace();
    76. }
    77. }
    78. list.add(new Object());
    79. System.out.println("【生产者" + Thread.currentThread().getName()
    80. + "】生产一个产品,现库存" + list.size());
    81. list.notifyAll();
    82. }
    83. }
    84. public void consume() {
    85. synchronized (list) {
    86. while (list.size() == 0) {
    87. System.out.println("【消费者" + Thread.currentThread().getName()
    88. + "】仓库为空");
    89. try {
    90. list.wait();
    91. } catch (InterruptedException e) {
    92. e.printStackTrace();
    93. }
    94. }
    95. list.remove();
    96. System.out.println("【消费者" + Thread.currentThread().getName()
    97. + "】消费一个产品,现库存" + list.size());
    98. list.notifyAll();
    99. }
    100. }
    101. }
    102. }