多线程六-线程通信之Condition使用与设计猜想
海上生明月,天涯共此时。愿大家在这个团圆的夜晚,收获满满的温馨和喜悦,团圆美满,中秋快乐!

使用示例
ConditionDemoAwait :开始之后加锁,阻塞并释放锁
package com.caozz.demo5.concurrent;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
public class ConditionDemoAwait implements Runnable{
    private Lock lock;
    private Condition condition;
    public ConditionDemoAwait(Lock lock, Condition condition){
        this.condition = condition;
        this.lock = lock;
    }
    @Override
    public void run() {
        System.out.println("begin---ConditoiopnDemoAwait--");
        lock.lock();
        try{
            condition.await();
            System.out.println("end---ConditoiopnDemoAwait--");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }
}
- ConditionDemoSinal :开始之后唤醒,此时并不会释放锁,所以会先结束,才会释放锁
package com.caozz.demo5.concurrent;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
public class ConditionDemoSinal implements Runnable{
    private Lock lock;
    private Condition condition;
    public ConditionDemoSinal(Lock lock, Condition condition){
        this.condition = condition;
        this.lock = lock;
    }
    @Override
    public void run() {
        System.out.println("begin---ConditoiopnDemoSinal--");
        lock.lock();
        try{
            //让当前线程阻塞,相当于Object.notify()
            condition.signal();
            System.out.println("end---ConditoiopnDemoSinal--");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }
}
测试:
package com.caozz.demo5.controller;
import com.caozz.demo5.concurrent.ConditionDemoAwait;
import com.caozz.demo5.concurrent.ConditionDemoSinal;
import com.caozz.demo5.concurrent.Consumer;
import com.caozz.demo5.concurrent.Producer;
import java.util.LinkedList;
import java.util.Queue;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Test {
    public static void main(String[] args) throws InterruptedException {
        Lock lock = new ReentrantLock();
        Condition condition = lock.newCondition();
        ConditionDemoAwait await = new ConditionDemoAwait(lock, condition);
        ConditionDemoSinal sinal = new ConditionDemoSinal(lock, condition);
        new Thread(await).start();
        Thread.sleep(10);
        new Thread(sinal).start();
    }
}
结果:
线程启动:await启动,执行开始后加锁,并阻塞,此时signal开始,并执行唤醒,然后signal结束,释放锁,被唤醒得await结束
如果启动不加sleep,可能会sinal先启动,那么sinal开始,唤醒,结束,然后await执行,阻塞,然后就会一直阻塞,无法结束,因为没有被唤醒
begin---ConditoiopnDemoAwait--
begin---ConditoiopnDemoSinal--
end---ConditoiopnDemoSinal--
end---ConditoiopnDemoAwait--
设计猜想
- 作用:实现线程的阻塞与唤醒
- 前提条件: 必须先要获得锁
- await、signal、signalall
- await:让线程阻塞,并且释放锁
- signal:唤醒阻塞的线程
 
- 加锁的操作,必然会涉及到AQS的阻塞队列
- await释放锁时,AQS队列中不存在已经释放锁的线程,那么被释放的线程去到了哪里?
- 唤醒被阻塞的线程:被阻塞的线程在哪里?
 经过上面的思考,应该可以想到,通过await方法释放的线程,必须要有一个地方来存储,同时,阻塞的线程,是通过AQS还是单独地方来存储呢?
Condition等价于wait/notify
Condition是JUC里面得实现,所以不能使用wait/notify ,锁的实现不同。
欢迎大家留言,以便于后面的人更快解决问题!另外亦欢迎大家可以关注我的微信公众号,方便利用零碎时间互相交流。共勉!

    ------愿来生只做陌上的看花人,无须入尘缘,仅行于陌上,看一川风花,无爱无伤-----
 
                    
                     
                    
                 
                    
                
 
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号