Condition 的简单使用

什么是 Condition?

Condition 是 java.util.concurrent.locks 包下的一个接口,该接口提供一个线程挂起执行的能力,直到给定的条件为真。Condition 对象必须绑定到 Lock,并使用 new Condition() 方法获取对象

Condition 的定义

Condition 接口的定义如下:

public interface Condition

Condition 中的方法

await()

使当前线程等待,直到发出信号或被中断为止

与此条件相关联的锁被原子释放,并且出于线程调度目的,当前线程被禁用,并且处于休眠状态,直到发生以下四种情况之一:

  • 其他一些线程为此条件调用 signal() 方法,并且当前线程恰好被选择为要唤醒的线程
  • 要么其他一些线程为此条件调用 signalAll() 方法
  • 要么其他一些线程中断当前线程,并支持中断线程挂起
  • 要么发生 “虚假唤醒”

在所有情况下,在此方法可以返回之前,当前线程必须重新获取与此条件关联的锁。 当线程返回时,可以保证保持此锁。

如果当前线程:

  • 在进入此方法时已设置其中断状态
  • 要么在等待期间中断并支持中断线程挂起,然后抛出InterruptedException并清除当前线程的中断状态。 在第一种情况下,没有规定在释放锁之前是否进行了中断测试
void await() throws InterruptedException

await(long time,TimeUnit unit)

使当前线程等待,直到发出信号或中断它,或者经过指定的等待时间。 此方法在行为上等效于:awaitNanos(unit.toNanos(time)) > 0

// time 表示等待的最长时间,unit 表示时间参数的时间单位
// 如果从方法返回之前等待时间已过,则返回false;否则返回true
boolean await(long time,TimeUnit unit) throws InterruptedException

awaitNanos(long nanosTimeout)

使当前线程等待,直到发出信号或中断它,或者经过指定的等待时间

long awaitNanos(long nanosTimeout) throws InterruptedException

awaitUninterruptibly()

使当前线程等待,直到发出信号

void awaitUninterruptibly()

awaitUntil(Date deadline)

使当前线程等待,直到发出信号或被中断或指定的截止时间过去为止

与此条件相关联的锁被原子释放,并且出于线程调度的目的,当前线程被禁用,并且处于休眠状态,直到发生以下五种情况之一:

  • 其他一些线程为此条件调用 signal() 方法,并且当前线程恰好被选择为要唤醒的线程
  • 其他一些线程为此条件调用 signalAll()方法
  • 其他一些线程中断当前线程,并支持中断线程挂起
  • 指定的期限已过
  • 发生 “虚假唤醒”
boolean awaitUntil(Date deadline) throws InterruptedException

signal()

唤醒一个等待线程

如果有任何线程在这种情况下等待,则选择一个线程进行唤醒。 然后,该线程必须重新获取锁,然后才能从等待返回

void signal()

signalAll()

唤醒所有等待的线程

如果有任何线程在这种情况下等待,那么它们都将被唤醒。 每个线程必须重新获取锁,然后才能从等待状态返回

void signalAll()

举例:(Condition 的使用)

package com.java.springtest.testdemo;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author Woo_home
 * @create by 2020/2/2
 */
public class TestThread {

    // 自定义一个队列
    static class ItemQueue {

        private Object[] items = null;

        private int current = 0;

        private int placeIndex = 0;

        private int removeIndex = 0;

        private Lock lock;

        private Condition isEmpty;

        private Condition isFull;

        public ItemQueue(int capacity) {
            this.items = new Object[capacity];
            lock = new ReentrantLock();
            isEmpty = lock.newCondition();
            isFull = lock.newCondition();
        }

        public void add(Object item) throws InterruptedException {
            lock.lock();
            while (current >= items.length) {
                isFull.await();
            }
            items[placeIndex] = item;
            placeIndex = (placeIndex + 1) % items.length;
            ++current;
            isEmpty.signal();
            lock.unlock();
        }

        public Object remove() throws InterruptedException {
            Object item = null;
            lock.lock();
            while (current <= 0) {
                isEmpty.await();
            }
            item = items[removeIndex];
            removeIndex = (removeIndex + 1) % items.length;
            --current;
            isFull.signal();
            lock.unlock();
            return item;
        }

        public boolean isEmpty() {
            return (items.length == 0);
        }
    }

    // 创建生产者并继承 Thread 类
    static class Producer extends Thread {

        private final ItemQueue itemQueue;

        public Producer(ItemQueue itemQueue) {
            this.itemQueue = itemQueue;
        }

        @Override
        public void run() {
            String[] numbers = {"1","2","3","4","5","6","7","8","9","10","11","12"};
            try {
                for (String number : numbers) {
                    itemQueue.add(number);
                    System.out.println("[Producer]:" + number);
                }
                itemQueue.add(null);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    // 创建消费者并继承 Thread 类
    static class Consumer extends Thread {

        private final ItemQueue itemQueue;

        public Consumer(ItemQueue itemQueue) {
            this.itemQueue = itemQueue;
        }

        @Override
        public void run() {
            try {
                do {
                    Object number = itemQueue.remove();
                    System.out.println("[Consumer]:" + number);
                    if (number == null) {
                        return;
                    }
                } while (!itemQueue.isEmpty());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) throws InterruptedException {
        ItemQueue itemQueue = new ItemQueue(10);

        // 创建生产者与消费者
        Thread producer = new Producer(itemQueue);
        Thread consumer = new Consumer(itemQueue);

        // 启动线程
        producer.start();
        consumer.start();

        // 等待两个线程终止
        producer.join();
        consumer.join();
    }
}

执行程序输出如下:

[Producer]1
[Producer]2
[Producer]3
[Producer]4
[Producer]5
[Producer]6
[Producer]7
[Producer]8
[Consumer]1
[Consumer]2
[Consumer]3
[Consumer]4
[Consumer]5
[Consumer]6
[Consumer]7
[Consumer]8
[Consumer]9
[Producer]9
[Producer]10
[Producer]11
[Producer]12
[Consumer]10
[Consumer]11
[Consumer]12
[Consumer]:null
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值