JUC--线程间协作Condition

Condition
  Condition是在java 1.5中才出现的,它用来替代传统的Object的wait()、notify()实现线程间的协作,相比使用Object的wait()、notify(),使用Condition1的await()、signal()这种方式实现线程间协作更加安全和高效。因此通常来说比较推荐使用Condition,在阻塞队列那一篇博文中就讲述到了,阻塞队列实际上是使用了Condition来模拟线程间协作。

  • Condition是个接口,基本的方法就是await()和signal()方法;
  • Condition依赖于Lock接口,生成一个Condition的基本代码是lock.newCondition()
  • 调用Condition的await()和signal()方法,都必须在lock保护之内,就是说必须在lock.lock()和lock.unlock之间才可以使用

Conditon中的await()对应Object的wait();

Condition中的signal()对应Object的notify();

Condition中的signalAll()对应Object的notifyAll()。

Condition 的基本使用

ConditionWait
public class AwaitThread implements Runnable{
 private Lock lock;
 private Condition condition;
 public AwaitThread (Lock lock, Condition condition){
 this.lock=lock;
 this.condition=condition;
 }
 @Override
 public void run() {
 System.out.println("begin -AwaitThread ");
 try {
 lock.lock();
 condition.await();
 System.out.println("end - AwaitThread ");
 } catch (InterruptedException e) {
 e.printStackTrace();
 }finally {
 lock.unlock();
 }
 }
}
ConditionSignal
public class SignalThread implements Runnable{
 private Lock lock;
 private Condition condition;
 public SignalThread (Lock lock, Condition condition){
 this.lock=lock;
 this.condition=condition;
 }
 @Override
 public void run() {
 System.out.println("begin -SignalThread ");
 try {
 lock.lock();
 condition.signal();
 System.out.println("end - SignalThread ");
 }finally {
 lock.unlock();
 }
 }
}

线程 awaitThread 先通过lock.lock()方法获取锁成功后调用了condition.await 方法进入等待队列,而另一个线程signalThread 通过 lock.lock()方法获取锁成功后调用了 condition.signal 或者 signalAll 方法,使得线程 awaitThread 能够有机会移入到同步队列中,当其他线程释放 lock 后使得线程awaitThread 能够有机会获取 lock,从而使得线程 awaitThread 能够从await 方法中退出执行后续操作。如果 awaitThread 获取 lock 失败会直接进入到同步队列。

生产者-消费者模型的实现

1.使用Object的wait()和notify()实现:

   public class Test {
      private int queueSize = 10;
      private PriorityQueue queue = new PriorityQueue(queueSize);
      
    public static void main(String[] args)  {
        Test test = new Test();
        Producer producer = test.new Producer();
        Consumer consumer = test.new Consumer();
          
        producer.start();
        consumer.start();
    }
      
    class Consumer extends Thread{
          
        @Override
        public void run() {
            consume();
        }
          
        private void consume() {
            while(true){
                synchronized (queue) {
                    while(queue.size() == 0){
                        try {
                            System.out.println("队列空,等待数据");
                            queue.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                            queue.notify();
                        }
                    }
                    queue.poll();          //每次移走队首元素
                    queue.notify();
                    System.out.println("从队列取走一个元素,队列剩余"+queue.size()+"个元素");
                }
            }
        }
    }
      
    class Producer extends Thread{
          
        @Override
        public void run() {
            produce();
        }
          
        private void produce() {
            while(true){
                synchronized (queue) {
                    while(queue.size() == queueSize){
                        try {
                            System.out.println("队列满,等待有空余空间");
                            queue.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                            queue.notify();
                        }
                    }
                    queue.offer(1);        //每次插入一个元素
                    queue.notify();
                    System.out.println("向队列取中插入一个元素,队列剩余空间:"+(queueSize-queue.size()));
                }
            }
        }
    }
}

2.使用Condition实现
Condition对象是由lock对象所创建的,但是同一个锁可以创建多个Condition对象,即创建多个对象监视器。这样的好处是可以指定唤醒线程。

public class Test {
    private int queueSize = 10;
    private PriorityQueue queue = new PriorityQueue(queueSize);
    private Lock lock = new ReentrantLock();
    private Condition notFull = lock.newCondition();
    private Condition notEmpty = lock.newCondition();
     
    public static void main(String[] args)  {
        Test test = new Test();
        Producer producer = test.new Producer();
        Consumer consumer = test.new Consumer();
          
        producer.start();
        consumer.start();
    }
      
    class Consumer extends Thread{
          
        @Override
        public void run() {
            consume();
        }
          
        private void consume() {
            while(true){
                lock.lock();
                try {
                    while(queue.size() == 0){
                        try {
                            System.out.println("队列空,等待数据");
                            notEmpty.await();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    queue.poll();                //每次移走队首元素
                    notFull.signal();
                    System.out.println("从队列取走一个元素,队列剩余"+queue.size()+"个元素");
                } finally{
                    lock.unlock();
                }
            }
        }
    }
      
    class Producer extends Thread{
          
        @Override
        public void run() {
            produce();
        }
          
        private void produce() {
            while(true){
                lock.lock();
                try {
                    while(queue.size() == queueSize){
                        try {
                            System.out.println("队列满,等待有空余空间");
                            notFull.await();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    queue.offer(1);        //每次插入一个元素
                    notEmpty.signal();
                    System.out.println("向队列取中插入一个元素,队列剩余空间:"+(queueSize-queue.size()));
                } finally{
                    lock.unlock();
                }
            }
        }
    }
}

大部分转自:https://www.cnblogs.com/dolphin0520/p/3920385.html

你可能感兴趣的:(JUC--线程间协作Condition)