synchronized wait()/notify 对比 ReentrantLock await()/signal()

打印 上一主题 下一主题

主题 991|帖子 991|积分 2973

结论

synchronized

   synchronized 共同 wait()/notify 无法实现精准唤醒线程
  ReentrantLock

   ReentrantLock 共同 Condition await()/signal() 可以实现精准唤醒线程 (指唤醒指定的线程)
  ReentrantLock 怎样实现精准唤醒线程

   一个 lock 共同多个 Condition, 且每个 Condition 中只有一个线程
(若一个Condition中有多个线程,也无法精准唤醒线程)
  案例 synchronized

  1. public class ManySync {
  2.     public void await1() {
  3.         synchronized (this) {
  4.             try {
  5.                 System.out.println("await1 - 进入等待" + Thread.currentThread().getName());
  6.                 this.wait();
  7.                 System.out.println("await1 - 被唤醒" + Thread.currentThread().getName());
  8.             } catch (Exception e) {
  9.                 e.printStackTrace();
  10.             }
  11.         }
  12.     }
  13.     public synchronized void await2() {
  14.         synchronized (this) {
  15.             try {
  16.                 System.out.println("await2 - 进入等待" + Thread.currentThread().getName());
  17.                 this.wait();
  18.                 System.out.println("await2 - 被唤醒" + Thread.currentThread().getName());
  19.             } catch (Exception e) {
  20.                 e.printStackTrace();
  21.             }
  22.         }
  23.     }
  24.     public void await3() {
  25.         synchronized (this) {
  26.             try {
  27.                 System.out.println("await3 - 进入等待" + Thread.currentThread().getName());
  28.                 this.wait();
  29.                 System.out.println("await3 - 被唤醒" + Thread.currentThread().getName());
  30.             } catch (Exception e) {
  31.                 e.printStackTrace();
  32.             }
  33.         }
  34.     }
  35.     public void await4() {
  36.         synchronized (this) {
  37.             try {
  38.                 System.out.println("await4 - 进入等待" + Thread.currentThread().getName());
  39.                 this.wait();
  40.                 System.out.println("await4 - 被唤醒" + Thread.currentThread().getName());
  41.             } catch (Exception e) {
  42.                 e.printStackTrace();
  43.             }
  44.         }
  45.     }
  46.     public  void notif() {
  47.         synchronized(this) {
  48.             try {
  49.                 this.notify();
  50.                 this.notify();
  51.                 this.notify();
  52.                 this.notify();
  53.             } catch (Exception e) {
  54.                 e.printStackTrace();
  55.             }
  56.         }
  57.     }
  58. }
  59. class Run3 {
  60.     public static void main(String[] args) {
  61.         try {
  62.             ManySync manySync = new ManySync();
  63.             Thread t1 = new Thread(() -> {
  64.                 manySync.await1();
  65.             });
  66.             Thread t2 = new Thread(() -> {
  67.                 manySync.await2();
  68.             });
  69.             Thread t3 = new Thread(() -> {
  70.                 manySync.await3();
  71.             });
  72.             Thread t4 = new Thread(() -> {
  73.                 manySync.await4();
  74.             });
  75.             t1.start();
  76.             Thread.sleep(200);
  77.             t2.start();
  78.             Thread.sleep(200);
  79.             t3.start();
  80.             Thread.sleep(200);
  81.             t4.start();
  82.             Thread.sleep(1000);
  83.             manySync.notif();
  84.         } catch (Exception e) {
  85.             e.printStackTrace();
  86.         }
  87.     }
  88. }
复制代码
输出结果 可以看出等待时间长的锁并不会开始被唤醒, 也无法唤醒指定线程,(因为并未提供能唤醒的API,也无法进行设计) 唤醒的输出结果是随机的 由 JVM 调理
  1. await1 - 进入等待Thread-0
  2. await2 - 进入等待Thread-1
  3. await3 - 进入等待Thread-2
  4. await4 - 进入等待Thread-3
  5. await1 - 被唤醒Thread-0
  6. await4 - 被唤醒Thread-3
  7. await3 - 被唤醒Thread-2
  8. await2 - 被唤醒Thread-1
复制代码
案例 ReentrantLock

  1. import java.util.concurrent.locks.Condition;
  2. import java.util.concurrent.locks.Lock;
  3. import java.util.concurrent.locks.ReentrantLock;
  4. public class ManyCondition {
  5.     private Lock lock = new ReentrantLock();
  6.     Condition condition1 = lock.newCondition();
  7.     Condition condition2 = lock.newCondition();
  8.     Condition condition3 = lock.newCondition();
  9.     Condition condition4 = lock.newCondition();
  10.      public void await1() {
  11.         try {
  12.             lock.lock();
  13.             System.out.println("await1 - 进入等待" + Thread.currentThread().getName());
  14.             condition1.await();
  15.             System.out.println("await1 - 被唤醒" + Thread.currentThread().getName());
  16.             lock.unlock();
  17.         } catch (Exception e) {
  18.             e.printStackTrace();
  19.         }
  20.     }
  21.     public void await2() {
  22.         try {
  23.             lock.lock();
  24.             System.out.println("await2 - 进入等待" + Thread.currentThread().getName());
  25.             condition2.await();
  26.             System.out.println("await2 - 被唤醒" + Thread.currentThread().getName());
  27.             lock.unlock();
  28.         } catch (Exception e) {
  29.             e.printStackTrace();
  30.         }
  31.     }
  32.     public void await3() {
  33.         try {
  34.             lock.lock();
  35.             System.out.println("await3 - 进入等待" + Thread.currentThread().getName());
  36.             condition3.await();
  37.             System.out.println("await3 - 被唤醒" + Thread.currentThread().getName());
  38.             lock.unlock();
  39.         } catch (Exception e) {
  40.             e.printStackTrace();
  41.         }
  42.     }
  43.     public void await4() {
  44.         try {
  45.             lock.lock();
  46.             System.out.println("await4 - 进入等待" + Thread.currentThread().getName());
  47.             condition4.await();
  48.             System.out.println("await4 - 被唤醒" + Thread.currentThread().getName());
  49.             lock.unlock();
  50.         } catch (Exception e) {
  51.             e.printStackTrace();
  52.         }
  53.     }
  54.     public void signal() {
  55.         try {
  56.             lock.lock();
  57.             System.out.println("await1 - 被唤醒 - " + Thread.currentThread().getName());
  58.             condition1.signal();
  59.             lock.unlock();
  60.             lock.lock();
  61.             System.out.println("await2 - 被唤醒 - " + Thread.currentThread().getName());
  62.             condition2.signal();
  63.             lock.unlock();
  64.             lock.lock();
  65.             System.out.println("await3 - 被唤醒 - " + Thread.currentThread().getName());
  66.             condition3.signal();
  67.             lock.unlock();
  68.             lock.lock();
  69.             System.out.println("await4 - 被唤醒 - " + Thread.currentThread().getName());
  70.             condition4.signal();
  71.             lock.unlock();
  72.         } catch (Exception e) {
  73.             e.printStackTrace();
  74.         }
  75.     }
  76. }
  77. class Run2 {
  78.     public static void main(String[] args) {
  79.              try {
  80.                 ManyCondition manyCondition = new ManyCondition();
  81.                 Thread t1 = new Thread(() -> {
  82.                     manyCondition.await1();
  83.                 });
  84.                 Thread t2 = new Thread(() -> {
  85.                     manyCondition.await2();
  86.                 });
  87.                 Thread t3 = new Thread(() -> {
  88.                     manyCondition.await3();
  89.                 });
  90.                 Thread t4 = new Thread(() -> {
  91.                     manyCondition.await4();
  92.                 });
  93.                 t1.start();
  94.                  t2.start();
  95.                  t3.start();
  96.                  t4.start();
  97.                 Thread.sleep(2000);
  98.                 manyCondition.signal();
  99.             } catch (Exception e) {
  100.                 e.printStackTrace();
  101.             }
  102.     }
  103. }
复制代码
输出结果 这里可以看出 ,当每个Condition 中只有一个线程时, 可以通过逻辑控制, 实现精准唤醒必要唤醒的线程
  1. await1 - 进入等待Thread-0
  2. await2 - 进入等待Thread-1
  3. await3 - 进入等待Thread-2
  4. await4 - 进入等待Thread-3
  5. await1 - 被唤醒 - main
  6. await2 - 被唤醒 - main
  7. await3 - 被唤醒 - main
  8. await4 - 被唤醒 - main
  9. await1 - 被唤醒Thread-0
  10. await2 - 被唤醒Thread-1
  11. await3 - 被唤醒Thread-2
  12. await4 - 被唤醒Thread-3
复制代码


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

何小豆儿在此

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表