多线程通信 wait和notify

Love The Way You Lie 2023-08-17 17:33 185阅读 0赞

一、概念
  线程是操作系统中独立的个体,这些线程如果不通过特殊的手段进行处理,就无法组成一个完整的整体。因此线程通信就称为组成一个整体的必须条件之一。当线程之间存在通信,那么系统之间的交互就会更加强大。在提高CPU使用率的前提下,会使开发人员对线程任务在开发的过程中进行有效的把控和监督。
   使用wait/notify实现线程之间的通信。这两个方法都是Object的类方法。也就是java的所有对象都提供了这两个方法。
   wait/notify必须配合关键字synchronize使用
   wait方法是释放锁,notify方法是不释放锁
1.异步通信

  1. import java.util.ArrayList;
  2. import java.util.List;
  3. import java.util.concurrent.CountDownLatch;
  4. public class ListAdd2 {
  5. private volatile static List list = new ArrayList();
  6. public void add(){
  7. list.add("bjsxt");
  8. }
  9. public int size(){
  10. return list.size();
  11. }
  12. public static void main(String[] args) {
  13. final ListAdd2 list2 = new ListAdd2();
  14. final Object lock = new Object();
  15. Thread t1 = new Thread(new Runnable() {
  16. @Override
  17. public void run() {
  18. try {
  19. synchronized (lock) {
  20. System.out.println("t1启动..");
  21. for(int i = 0; i <10; i++){
  22. list2.add();
  23. System.out.println("当前线程:" + Thread.currentThread().getName() + "添加了一个元素..");
  24. Thread.sleep(500);
  25. if(list2.size() == 5){
  26. System.out.println("已经发出通知..");
  27. lock.notify();
  28. }
  29. }
  30. }
  31. } catch (InterruptedException e) {
  32. e.printStackTrace();
  33. }
  34. }
  35. }, "t1");
  36. Thread t2 = new Thread(new Runnable() {
  37. @Override
  38. public void run() {
  39. synchronized (lock) {
  40. System.out.println("t2启动..");
  41. if(list2.size() != 5){
  42. try {
  43. lock.wait();
  44. } catch (InterruptedException e) {
  45. e.printStackTrace();
  46. }
  47. }
  48. System.out.println("当前线程:" + Thread.currentThread().getName() + "收到通知线程停止..");
  49. throw new RuntimeException();
  50. }
  51. }
  52. }, "t2");
  53. t2.start(); // 注意此处,t2线程先启动
  54. t1.start();
  55. }
  56. }

2.实时通信

  1. public class ListAdd3 {
  2. private volatile static List list = new ArrayList();
  3. final static CountDownLatch countDownLatch = new CountDownLatch(1); // 数字表示发起几次通知,线程才会被唤醒,如果为2,则需要写两次通知,如代码中注释
  4. public void add(){
  5. list.add("bjsxt");
  6. }
  7. public int size(){
  8. return list.size();
  9. }
  10. public static void main(String[] args) {
  11. final ListAdd3 list2 = new ListAdd3();
  12. final Object lock = new Object();
  13. Thread t1 = new Thread(new Runnable() {
  14. @Override
  15. public void run() {
  16. try {
  17. // synchronized (lock) {
  18. System.out.println("t1启动..");
  19. for(int i = 0; i <10; i++){
  20. list2.add();
  21. System.out.println("当前线程:" + Thread.currentThread().getName() + "添加了一个元素..");
  22. Thread.sleep(500);
  23. if(list2.size() == 5){
  24. System.out.println("已经发出通知..");
  25. countDownLatch.countDown();
  26. //countDownLatch.countDown(); // 如果括号中数字为2,则这里写几次
  27. // lock.notify();
  28. }
  29. }
  30. // }
  31. } catch (InterruptedException e) {
  32. e.printStackTrace();
  33. }
  34. }
  35. }, "t1");
  36. Thread t2 = new Thread(new Runnable() {
  37. @Override
  38. public void run() {
  39. //synchronized (lock) {
  40. System.out.println("t2启动..");
  41. if(list2.size() != 5){
  42. try {
  43. //lock.wait();
  44. countDownLatch.await();
  45. } catch (InterruptedException e) {
  46. e.printStackTrace();
  47. }
  48. }
  49. System.out.println("当前线程:" + Thread.currentThread().getName() + "收到通知线程停止..");
  50. throw new RuntimeException();
  51. }
  52. // }
  53. }, "t2");
  54. t2.start();
  55. t1.start();
  56. }
  57. }
  58. import java.util.ArrayList;
  59. import java.util.List;
  60. public class ListAdd1 {
  61. private volatile static List list = new ArrayList();
  62. public void add(){
  63. list.add("bjsxt");
  64. }
  65. public int size(){
  66. return list.size();
  67. }
  68. public static void main(String[] args) {
  69. final ListAdd1 list1 = new ListAdd1();
  70. Thread t1 = new Thread(new Runnable() {
  71. @Override
  72. public void run() {
  73. try {
  74. for(int i = 0; i <10; i++){
  75. list1.add();
  76. System.out.println("当前线程:" + Thread.currentThread().getName() + "添加了一个元素..");
  77. Thread.sleep(500);
  78. }
  79. } catch (InterruptedException e) {
  80. e.printStackTrace();
  81. }
  82. }
  83. }, "t1");
  84. Thread t2 = new Thread(new Runnable() {
  85. @Override
  86. public void run() {
  87. while(true){
  88. if(list1.size() == 5){
  89. System.out.println("当前线程收到通知:" + Thread.currentThread().getName() + " list size = 5 线程停止..");
  90. throw new RuntimeException();
  91. }
  92. }
  93. }
  94. }, "t2");
  95. t1.start();
  96. t2.start();
  97. }
  98. }

发表评论

表情:
评论列表 (有 0 条评论,185人围观)

还没有评论,来说两句吧...

相关阅读

    相关 线通信 waitnotify

    一、概念   线程是操作系统中独立的个体,这些线程如果不通过特殊的手段进行处理,就无法组成一个完整的整体。因此线程通信就称为组成一个整体的必须条件之一。当线程之间存在通