Condition:
void await() :造成当前线程在接到信号或被中断之前一直处于等待状态。
void await(long time, TimeUnit unit) :造成当前线程在接到信号、被中断或到达指定等待时间之前一直处于等待状态
long awaitNanos(long nanosTimeout) :造成当前线程在接到信号、被中断或到达指定等待时间之前一直处于等待状态。返回值表示剩余时间,如果在nanosTimesout之前唤醒,那么返回值 = nanosTimeout - 消耗时间,如果返回值 <= 0 ,则可以认定它已经超时了。
void awaitUninterruptibly() :造成当前线程在接到信号之前一直处于等待状态。【注意:该方法对中断不敏感】。
boolean awaitUntil(Date deadline) :造成当前线程在接到信号、被中断或到达指定最后期限之前一直处于等待状态。如果没有到指定时间就被通知,则返回true,否则表示到了指定时间,返回返回false。
void signal() :唤醒一个等待线程。该线程从等待方法返回前必须获得与Condition相关的锁。
void signalAll() :唤醒所有等待线程。能够从等待方法返回的线程必须获得与Condition相关的锁。
消费者:
public class Consumer implements Runnable{
private Queue<String> messageQueue;
private Lock lock;
private Condition condition;
public Consumer(Queue<String> messageQueue, Lock lock, Condition condition) {
this.messageQueue = messageQueue;
this.lock = lock;
this.condition = condition;
}
@Override
public void run() {
int i=0;
while(true){
i++;
lock.lock();
while(messageQueue.isEmpty()){
System.out.println("消费者队列空了,先等待");
try {
condition.await(); // 阻塞当前线程并释放锁
} catch (InterruptedException e) {
e.printStackTrace();
}
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("消费者消息"+i+":"+ messageQueue.remove());
condition.signal(); //唤醒一个阻塞的线程
lock.unlock();
}
}
}
生产者:
public class Producer implements Runnable {
private Queue<String> msg;
private int maxSize;
private Lock lock;
private Condition condition;
public Producer(Queue<String> msg, int maxSize, Lock lock, Condition condition) {
this.msg = msg;
this.maxSize = maxSize;
this.lock = lock;
this.condition = condition;
}
@Override
public void run() {
int i = 0;
while (true) {
i++;
lock.lock();
while (msg.size() == maxSize) {
System.out.println("生产者队列满了,先等待");
try {
condition.await(); // 阻塞当前线程并释放锁
} catch (InterruptedException e) {
e.printStackTrace();
}
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
String message = "消息" + i;
System.out.println("生产者生产消息:" + message);
msg.add(message);
condition.signal(); //唤醒一个阻塞的线程
lock.unlock();
}
}
}
测试:
public class Test {
public static void main(String[] args) {
Queue<String> queue = new LinkedList<>();
Lock lock = new ReentrantLock(); //重入锁
Condition condition = lock.newCondition();
int maxSize = 5;
Producer producer = new Producer(queue, maxSize, lock, condition);
Consumer consumer = new Consumer(queue, lock, condition);
Thread producerThread = new Thread(producer);
Thread consumerThread = new Thread(consumer);
producerThread.start();
consumerThread.start();
}
}
结果:
消费者队列空了,先等待
生产者生产消息:消息1
生产者生产消息:消息2
生产者生产消息:消息3
生产者生产消息:消息4
生产者生产消息:消息5
生产者队列满了,先等待
消费者消息1:消息1
消费者消息2:消息2
消费者消息3:消息3
消费者消息4:消息4
消费者消息5:消息5
消费者队列空了,先等待
生产者生产消息:消息6
...