Condition的认识
- Condition中的await()方法相当于Object的wait()方法
- Condition中的signal()方法相当于Object的notify()方法
- Condition中的signalAll()相当于Object的notifyAll()方法。
- Condition能够更加精细的控制多线程的休眠与唤醒。对于同一个锁,我们可以创建多个Condition,在不同的情况下使用不同的Condition,唤醒不同的线程,从而实现业务之间的通信。
ReentrantLock锁的使用
- void lock(); // 无条件的锁;
- void lockInterruptibly throws InterruptedException;//可中断的锁;
使用ReentrantLock如果获取了锁立即返回,如果没有获取锁,当前线程处于休眠状态,直到获得锁或者当前线程可以被别的线程中断去做其他的事情;但是如果是synchronized的话,如果没有获取到锁,则会一直等待下去; - boolean tryLock();//如果获取了锁立即返回true,如果别的线程正持有,立即返回false,不会等待;
- boolean tryLock(long timeout,TimeUnit unit);//如果获取了锁立即返回true,如果别的线程正持有锁,会等待参数给的时间,在等待的过程中,如果获取锁,则返回true,如果等待超时,返回false;
package condition;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* Description:
* A 执行完 调用B
* B 执行完 调用C
* C 执行完 调用A
* @author jiaoqianjin
* Date: 2020/8/11 9:58
**/
public class ConditionDemo {
public static void main(String[] args) {
Data3 data3 = new Data3();
new Thread(() -> {
for (int i = 0; i < 10; i++) {
data3.printA();
}
},"A").start();
new Thread(() -> {
for (int i = 0; i < 10; i++) {
data3.printB();
}
},"B").start();
new Thread(() -> {
for (int i = 0; i < 10; i++) {
data3.printC();
}
},"C").start();
}
}
class Data3 {
private Lock lock = new ReentrantLock();
private Condition condition1 = lock.newCondition();
private Condition condition2 = lock.newCondition();
private Condition condition3 = lock.newCondition();
//这个是线程之间进行调度的标志符
private int num = 1; // 1A 2B 3C
public void printA() {
lock.lock();
try {
/**
* 业务代码 判断 -> 执行 -> 通知
* 注意这里是用的是while循环判断,不能用if循环判断,如果使用if循环判断可能会出现虚假唤醒,
* 当两个线程同时执行到这里的时候只判断一次就会导致同时持有锁,所以我们需要使用while循环
*/
while (num != 1) {
//这个await方法相当于Object的wait方法,表明该方法的调用者放弃锁的持有,进入等待池,只有使用condition1的signal方法才能唤醒进入准备池
condition1.await();
}
System.out.println(Thread.currentThread().getName() + "==> AAAA" );
num = 2;
//这个signal方法相当于Object的notify方法, 唤醒使用condition2等待的线程进入准备池
condition2.signal();
TimeUnit.SECONDS.sleep(1);
}catch (Exception e) {
e.printStackTrace();
}finally {
lock.unlock();
}
}
public void printB() {
lock.lock();
try {
// 业务代码 判断 -> 执行 -> 通知
while (num != 2) {
//这个await方法相当于Object的wait方法,表明该方法的调用者放弃锁的持有,进入等待池,只有使用condition2的signal方法才能唤醒进入准备池
condition2.await();
}
System.out.println(Thread.currentThread().getName() + "==> BBBB" );
num = 3;
//这个signal方法相当于Object的notify方法, 唤醒使用condition3等待的线程进入准备池
condition3.signal();
TimeUnit.SECONDS.sleep(1);
}catch (Exception e) {
e.printStackTrace();
}finally {
lock.unlock();
}
}
public void printC() {
lock.lock();
try {
// 业务代码 判断 -> 执行 -> 通知
while (num != 3) {
//这个await方法相当于Object的wait方法,表明该方法的调用者放弃锁的持有,进入等待池,只有使用condition3的signal方法才能唤醒进入准备池
condition3.await();
}
System.out.println(Thread.currentThread().getName() + "==> CCCC" );
num = 1;
//这个signal方法相当于Object的notify方法, 唤醒使用condition1等待的线程进入准备池
condition1.signal();
TimeUnit.SECONDS.sleep(1);
}catch (Exception e) {
e.printStackTrace();
}finally {
lock.unlock();
}
}
}