多线程之间的交互

系统管理员 2023-08-17 17:07 116阅读 0赞

像在一个参数版本中,中断和虚假唤醒是可能的,并且该方法应该始终在循环中使用:

  1. synchronized (obj) {
  2. while (<condition does not hold>)
  3. obj.wait();
  4. ... // Perform action appropriate to condition
  5. }

不能使用if来判断,应该使用while。

在多线程中判断使用while

  1. package cn.zh.juc1205;
  2. class Aircondition {
  3. private int number = 0;
  4. public synchronized void increment() throws Exception {
  5. //判断
  6. while (number != 0) {
  7. this.wait();
  8. }
  9. number++;
  10. System.out.println(Thread.currentThread().getName()+"\t" +number);
  11. //通知
  12. this.notifyAll();
  13. }
  14. public synchronized void decrement() throws Exception {
  15. //判断
  16. while (number == 0) {
  17. this.wait();
  18. }
  19. number--;
  20. System.out.println(Thread.currentThread().getName()+"\t" +number);
  21. //通知
  22. this.notifyAll();
  23. }
  24. }
  25. /**
  26. *题目:现在两个线程,可以操作初始值为零的一个变量,
  27. * 实现一个线程对该变量加1,一个线程对该变量减1,
  28. * 实现交替,来10轮,变量初始值为零
  29. * 1.高内聚低耦合前提下,线程操作资源类
  30. * 2.判断/干活/通知
  31. * 3.防止虚假唤醒
  32. */
  33. public class ProdConsumerDemo04 {
  34. public static void main(String[] args) throws Exception {
  35. Aircondition aircondition = new Aircondition();
  36. new Thread(()->{
  37. for (int i = 1; i <= 10; i++) {
  38. try {
  39. aircondition.increment();
  40. } catch (Exception e) {
  41. e.printStackTrace();
  42. }
  43. }
  44. },"A").start();
  45. new Thread(()->{
  46. for (int i = 1; i <= 10; i++) {
  47. try {
  48. aircondition.decrement();
  49. } catch (Exception e) {
  50. e.printStackTrace();
  51. }
  52. }
  53. },"B").start();
  54. new Thread(()->{
  55. for (int i = 1; i <= 10; i++) {
  56. try {
  57. aircondition.increment();
  58. } catch (Exception e) {
  59. e.printStackTrace();
  60. }
  61. }
  62. },"C").start();
  63. new Thread(()->{
  64. for (int i = 1; i <= 10; i++) {
  65. try {
  66. aircondition.decrement();
  67. } catch (Exception e) {
  68. e.printStackTrace();
  69. }
  70. }
  71. },"D").start();
  72. }
  73. }
  74. package cn.zh.juc1205;
  75. import java.util.concurrent.locks.Condition;
  76. import java.util.concurrent.locks.Lock;
  77. import java.util.concurrent.locks.ReentrantLock;
  78. class ShareData {
  79. private int number = 1;//A:1 B:2 C:3定义标志位
  80. private Lock lock = new ReentrantLock();
  81. private Condition c1 = lock.newCondition();
  82. private Condition c2 = lock.newCondition();
  83. private Condition c3 = lock.newCondition();
  84. public void print5() {
  85. lock.lock();
  86. try {
  87. //1.判断
  88. while (number != 1) {
  89. c1.await();
  90. }
  91. //2.打印五次
  92. for (int i = 0; i < 5; i++) {
  93. System.out.println(Thread.currentThread().getName()+"\t"+i);
  94. }
  95. //3.通知 如何通知第二个
  96. number = 2;
  97. c2.signalAll();
  98. } catch (Exception e) {
  99. e.printStackTrace();
  100. } finally {
  101. lock.unlock();
  102. }
  103. }
  104. public void print10() {
  105. lock.lock();
  106. try {
  107. //1.判断
  108. while (number != 2) {
  109. c2.await();
  110. }
  111. //2.打印五次
  112. for (int i = 0; i < 10; i++) {
  113. System.out.println(Thread.currentThread().getName()+"\t"+i);
  114. }
  115. //3.通知 如何通知第二个
  116. number = 3;
  117. c3.signalAll();
  118. } catch (Exception e) {
  119. e.printStackTrace();
  120. } finally {
  121. lock.unlock();
  122. }
  123. }
  124. public void print15() {
  125. lock.lock();
  126. try {
  127. //1.判断
  128. while (number != 3) {
  129. c3.await();
  130. }
  131. //2.打印五次
  132. for (int i = 0; i < 15; i++) {
  133. System.out.println(Thread.currentThread().getName()+"\t"+i);
  134. }
  135. //3.通知 如何通知第二个
  136. number = 1;
  137. c1.signalAll();
  138. } catch (Exception e) {
  139. e.printStackTrace();
  140. } finally {
  141. lock.unlock();
  142. }
  143. }
  144. }
  145. /**
  146. * 备注多线程之间按顺序调用 实现A->B->C
  147. * 三个线程启动,要求如下:
  148. * AA打印5次,BB打印10次,CC打印15次
  149. * 接着
  150. * AA打印5次,BB打印10次,CC打印15次
  151. *
  152. */
  153. public class ConditionDemo {
  154. public static void main(String[] args) {
  155. ShareData shareData = new ShareData();
  156. new Thread(()->{
  157. for (int i = 1;i <= 10; i++) {
  158. shareData.print5();
  159. }
  160. },"A").start();
  161. new Thread(()->{
  162. for (int i = 1;i <= 10; i++) {
  163. shareData.print10();
  164. }
  165. },"B").start();
  166. new Thread(()->{
  167. for (int i = 1;i <= 10; i++) {
  168. shareData.print15();
  169. }
  170. },"C").start();
  171. }
  172. }

发表评论

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

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

相关阅读

    相关 线之间竞争

          进行多线程编程,同步控制是非常重要的,而同步控制就涉及到了锁。        对代码进行同步控制我们可以选择同步方法,也可以选择同步块,这两种方式各有优缺点,至于