22.线程通信Condition

Condition

    通过此对象可以与lock实现组合使用,为每个对象提供多个等待,实现多个阻塞队列。
  1. package dmeo9;
  2. import java.util.concurrent.locks.Condition;
  3. import java.util.concurrent.locks.Lock;
  4. import java.util.concurrent.locks.ReentrantLock;
  5. public class DemoLock2 {
  6. private Lock lock = new ReentrantLock();
  7. private Condition condition1 = lock.newCondition();
  8. public void m1(){
  9. try {
  10. lock.lock();
  11. System.err.println(Thread.currentThread().getName()+":线程,进入m1");
  12. Thread.sleep(3000);
  13. System.err.println(Thread.currentThread().getName()+":线程,释放锁,接收通唤醒知");
  14. condition1.await();
  15. System.err.println(Thread.currentThread().getName()+":线程,继续执行 m1");
  16. } catch (InterruptedException e) {
  17. e.printStackTrace();
  18. }finally {
  19. lock.unlock();
  20. }
  21. }
  22. public void m2(){
  23. try {
  24. lock.lock();
  25. System.err.println(Thread.currentThread().getName()+":线程,进入m2");
  26. Thread.sleep(3000);
  27. System.err.println(Thread.currentThread().getName()+":线程,发出通知,唤醒");
  28. condition1.signal();
  29. System.err.println(Thread.currentThread().getName()+":线程,继续执行 m2");
  30. } catch (InterruptedException e) {
  31. e.printStackTrace();
  32. }finally {
  33. lock.unlock();
  34. }
  35. }
  36. public static void main(String[] atgs) {
  37. final DemoLock2 demoLock = new DemoLock2();
  38. Thread t1 = new Thread(new Runnable() {
  39. @Override
  40. public void run() {
  41. demoLock.m1();;
  42. }
  43. },"消费者t1");
  44. Thread t2 = new Thread(new Runnable() {
  45. @Override
  46. public void run() {
  47. demoLock.m2();;
  48. }
  49. },"生产者t2");
  50. t1.start();
  51. t2.start();
  52. }
  53. }
  54. 输出:
  55. 消费者t1:线程,进入m1 消费者t1:线程,释放锁,接收通唤醒知 生产者t2:线程,进入m2 生产者t2:线程,发出通知,唤醒 生产者t2:线程,继续执行 m2 消费者t1:线程,继续执行 m1

多Condition组合

  1. package dmeo9;
  2. import java.util.concurrent.locks.Condition;
  3. import java.util.concurrent.locks.Lock;
  4. import java.util.concurrent.locks.ReentrantLock;
  5. /**
  6. * Created by liudan on 2017/8/4.
  7. */
  8. public class DemoLock3 {
  9. /**
  10. * 通过一对象产生lock对象,并生产多个Condition进行多线程的交互,可以做到一部分唤醒,另一部分继续等待。
  11. */
  12. private Lock lock = new ReentrantLock();
  13. private Condition condition1 = lock.newCondition();
  14. private Condition condition2 = lock.newCondition();
  15. public void m1() {
  16. try {
  17. lock.lock();
  18. System.err.println(Thread.currentThread().getName() + ":进入m1");
  19. Thread.sleep(100);
  20. System.err.println(Thread.currentThread().getName() + ":m1释放锁,接收通唤醒知");
  21. condition1.await();
  22. System.err.println(Thread.currentThread().getName() + ":继续执行 m1");
  23. } catch (InterruptedException e) {
  24. e.printStackTrace();
  25. } finally {
  26. lock.unlock();
  27. }
  28. }
  29. public void m2() {
  30. try {
  31. lock.lock();
  32. System.err.println(Thread.currentThread().getName() + ":进入m2");
  33. Thread.sleep(200);
  34. System.err.println(Thread.currentThread().getName() + ":m2释放锁,接收通唤醒知");
  35. condition1.await();
  36. System.err.println(Thread.currentThread().getName() + ":继续执行 m2");
  37. } catch (InterruptedException e) {
  38. e.printStackTrace();
  39. } finally {
  40. lock.unlock();
  41. }
  42. }
  43. public void m3() {
  44. try {
  45. lock.lock();
  46. System.err.println(Thread.currentThread().getName() + ":进入m3");
  47. Thread.sleep(300);
  48. System.err.println(Thread.currentThread().getName() + ":m3释放锁,接收通唤醒知");
  49. condition2.await();
  50. System.err.println(Thread.currentThread().getName() + ":继续执行 m3");
  51. } catch (InterruptedException e) {
  52. e.printStackTrace();
  53. } finally {
  54. lock.unlock();
  55. }
  56. }
  57. public void m4() {
  58. try {
  59. lock.lock();
  60. System.err.println(Thread.currentThread().getName() + ":进入m4");
  61. Thread.sleep(400);
  62. System.err.println(Thread.currentThread().getName() + ":m4发出通知并唤醒:m1、m2");
  63. condition1.signalAll();
  64. } catch (InterruptedException e) {
  65. e.printStackTrace();
  66. } finally {
  67. lock.unlock();
  68. }
  69. }
  70. public void m5() {
  71. try {
  72. lock.lock();
  73. System.err.println(Thread.currentThread().getName() + ":进入m5");
  74. Thread.sleep(500);
  75. System.err.println(Thread.currentThread().getName() + ":m5发出通知并唤醒:m3");
  76. condition2.signal();
  77. } catch (InterruptedException e) {
  78. e.printStackTrace();
  79. } finally {
  80. lock.unlock();
  81. }
  82. }
  83. public static void main(String[] atgs) {
  84. DemoLock3 demoLock3 = new DemoLock3();
  85. Thread t1 = new Thread(new Runnable() {
  86. @Override
  87. public void run() {
  88. demoLock3.m1();
  89. }
  90. }, "_1");
  91. Thread t2 = new Thread(new Runnable() {
  92. @Override
  93. public void run() {
  94. demoLock3.m2();
  95. }
  96. }, "_2");
  97. Thread t3 = new Thread(new Runnable() {
  98. @Override
  99. public void run() {
  100. demoLock3.m3();
  101. }
  102. }, "_3");
  103. Thread t4 = new Thread(new Runnable() {
  104. @Override
  105. public void run() {
  106. demoLock3.m4();
  107. }
  108. }, "_4");
  109. Thread t5 = new Thread(new Runnable() {
  110. @Override
  111. public void run() {
  112. demoLock3.m5();
  113. }
  114. }, "_5");
  115. t1.start();
  116. t2.start();
  117. t3.start();
  118. try {
  119. Thread.sleep(3000);
  120. } catch (InterruptedException e) {
  121. e.printStackTrace();
  122. }
  123. t4.start();
  124. try {
  125. Thread.sleep(3000);
  126. } catch (InterruptedException e) {
  127. e.printStackTrace();
  128. }
  129. t5.start();
  130. }
  131. }
  132. 输出:
  133. _1:进入m1 _1:m1释放锁,接收通唤醒知 _2:进入m2 _2:m2释放锁,接收通唤醒知 _3:进入m3 _3:m3释放锁,接收通唤醒知 _4:进入m4 _4:m4发出通知并唤醒:m1、m2 _1:继续执行 m1 _2:继续执行 m2 _5:进入m5 _5:m5发出通知并唤醒:m3 _3:继续执行 m3

常用方法

  1. * 公平锁、非公平锁
  2. * Lock lock = new ReentrantLock(boolean isFair)。
  3. * tryLock()尝试去获取锁,并获得结果用false、true返回,并在给定的时间内去获取。
  4. * isFair():是否公平锁。
  5. * isLocked():是否锁定
  6. * getHoldCount():查询当前的线程保存的锁存在的个数,也就是调用lock的次数。
  7. * lockinterruptibly():优先响应中断的锁。
  8. * getQueueLength():返回正在等待获取此锁的线程数量。
  9. * getWaitQueueLenth():获取返回等待与锁定相关的给定条件condition的线程数量。
  10. * hasQueuedThread(Thread thread):查询指定的线程是否正在等待此锁。
  11. * hasQueuedThread():查询是否有线程正在等待次锁。
  12. * hasWaiters():查询是否有线程正在等待与此锁有关的condition条件。
posted @ 2017-08-10 02:05  逍遥叹!!  阅读(184)  评论(0编辑  收藏  举报