作用:使当前线程进入等待状,并交换执行执,等待被交换的当前执行线程唤醒,才可以继续执行,如果不被唤醒?
场景:多个线程操作同一个共享资源时使用。
Condition 是执行条件。类似传统技术中的 wait 的 notify 功能。
Condition 是基于一个 lock 而存在。
注意的是,Condition 的创建来自同一个 lock 对象,
Condition 也行 wait 也好,套路就是使用三个工具来完成三步套路。即,用两个线程,同时跑两个代码,并且用 while 不段的去读取一个条件,来判断自己是否应该唤醒对方。
步骤:
- 先lock住
- 通过 lock 拿到 condition。再进行操作如 await
- 然后多个线程开始 await、single
注意 await 会释放锁。
1
| await()的作用是能够让其他线程访问竞争资源,所以挂起状态就是要释放竞争资源的锁。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
| package com.liukai.thread.lock.condition;
import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock;
public class TestCondition {
private final Lock lock = new ReentrantLock(); private final Condition full = lock.newCondition(); private final Condition notFull = lock.newCondition(); private int count = 0; private int takeptr = 0; private int putptr = 0; Object [] blockArray = new Object[100];
public static void main(String[] args) { final TestCondition condition = new TestCondition(); for (int i = 0; i < 100; i++) { new Thread(()->{ try { condition.put(new Object()); } catch (InterruptedException e) { e.printStackTrace(); } }).start();
new Thread(()->{ try { condition.take(); } catch (InterruptedException e) { e.printStackTrace(); } }).start();
} }
public void put (Object element) throws InterruptedException { try { lock.lock(); while (count == blockArray.length) { System.out.println("put: putptr = " + putptr + ", await"); full.await(); } System.out.println("put: putptr = " + putptr + ", 执行 put"); blockArray[putptr] = element; if (++putptr == blockArray.length) { putptr = 0; } ++count; notFull.signal(); } finally { lock.unlock(); } }
public Object take() throws InterruptedException { lock.lock(); Object data = null; try { while (0 == count) { System.out.println("take: takeptr == " + takeptr + ",await"); notFull.await(); } System.out.println("take: takeptr = " + takeptr + ", 执行 take"); data = blockArray[takeptr]; if (++takeptr == blockArray.length) { takeptr = 0; } --count; full.signal(); return data; } finally { lock.unlock(); } } }
|