java.util.concurrent.locks.Condition
接口提供一个线程挂起执行的能力,直到给定的条件为真。 Condition
对象必须绑定到Lock
,并使用newCondition()
方法获取对象。
Condition类的方法
以下是Condition
类中可用的重要方法的列表。
序号 | 方法名称 | 描述 |
---|---|---|
1 | public void await() |
使当前线程等待,直到发出信号或中断信号。 |
2 | public boolean await(long time, TimeUnit unit) |
使当前线程等待直到发出信号或中断,或指定的等待时间过去。 |
3 | public long awaitNanos(long nanosTimeout) |
使当前线程等待直到发出信号或中断,或指定的等待时间过去。 |
4 | public long awaitUninterruptibly() |
使当前线程等待直到发出信号。 |
5 | public long awaitUntil() |
使当前线程等待直到发出信号或中断,或者指定的最后期限过去。 |
6 | public void signal() |
唤醒一个等待线程。 |
7 | public void signalAll() |
唤醒所有等待线程。 |
实例
以下TestThread
程序演示了Condition
接口的这些方法。这里我们使用signal()
通知和await()
挂起线程。
import java.util.concurrent.locks.Condition
import java.util.concurrent.locks.Lock
import java.util.concurrent.locks.ReentrantLock
public class TestThread {
public static void main(String[] args) throws InterruptedException{
ItemQueue itemQueue = new ItemQueue(10)
//Create a producer and a consumer.
Thread producer = new Producer(itemQueue)
Thread consumer = new Consumer(itemQueue)
//Start both threads.
producer.start()
consumer.start()
//Wait for both threads to terminate.
producer.join()
consumer.join()
}
static class ItemQueue {
private Object[] items = null
private int current = 0
private int placeIndex = 0
private int removeIndex = 0
private final Lock lock
private final Condition isEmpty
private final 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
//Notify the consumer that there is data available.
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
//Notify the producer that there is space available.
isFull.signal()
lock.unlock()
return item
}
public boolean isEmpty(){
return (items.length == 0)
}
}
static class Producer extends Thread {
private final ItemQueue queue
public Producer(ItemQueue queue) {
this.queue = queue
}
@Override
public void run() {
String[] numbers = {"1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"}
try {
for(String number: numbers){
queue.add(number)
System.out.println("[Producer]: " + number)
}
queue.add(null)
}
catch (InterruptedException ex) {
ex.printStackTrace()
}
}
}
static class Consumer extends Thread {
private final ItemQueue queue
public Consumer(ItemQueue queue) {
this.queue = queue
}
@Override
public void run() {
try {
do {
Object number = queue.remove()
System.out.println("[Consumer]: " + number)
if(number == null){
return
}
} while(!queue.isEmpty())
}
catch (InterruptedException ex) {
ex.printStackTrace()
}
}
}
}
这将产生以下结果。
[Producer]: 1
[Consumer]: 1
[Producer]: 2
[Consumer]: 2
[Producer]: 3
[Consumer]: 3
[Producer]: 4
[Consumer]: 4
[Producer]: 5
[Producer]: 6
[Consumer]: 5
[Producer]: 7
[Consumer]: 6
[Consumer]: 7
[Producer]: 8
[Consumer]: 8
[Producer]: 9
[Consumer]: 9
[Producer]: 10
[Consumer]: 10
[Producer]: 11
[Consumer]: 11
[Producer]: 12
[Consumer]: 12
[Consumer]: null