并发编程-Condition
Condition
一个Lock中应该绑定一个Condition对象。Condition是Java提供用来实现等待/通知的类。
我们知道Object对象提供了wait、waitAll、notify、notifyAll的方法用来实现线程的同步、等待和唤醒。
但Condition类提供了比wait/notify更丰富的功能,Condition对象由lock对象所创建的,同时一个Lock可以创建多个Condition对象,即创建多个对象监听器,这样就可以指定唤醒具体线程,而notify是随机唤醒线程。
Condition接口
- void await():造成当前线程在接到信号或被中断之前一直处于等待状态。
- boolean await(long time, TimeUnit unit):造成当前线程在接到信号、被中断或到达指定等待时间之前一直处于等待状态。
- long awaitNanos(long nanosTimeout):造成当前线程在接到信号、被中断或到达指定等待时间之前一直处于等待状态。
- void awaitUninterruptibly():造成当前线程在接到信号之前一直处于等待状态。
- boolean awaitUntil(Date deadline):造成当前线程在接到信号、被中断或到达指定最后期限之前一直处于等待状态。
- void signal():唤醒一个等待线程。
范例
public class Resource {
private final int MAX_SIZE = 10;
private List<Object> list = Lists.newArrayList();
private Lock lock = new ReentrantLock();
private Condition produceCondition = lock.newCondition();
private Condition consumerCondition = lock.newCondition();
public void produce() {
while (true) {
lock.lock();
try {
while (list.size() == MAX_SIZE) {
System.out.println("生产满了,暂时无法生产:" + list.size());
consumerCondition.signal();
try {
produceCondition.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
list.add(new Object());
System.out.println(Thread.currentThread().getName() + "生产新产品,共有:" + list.size());
} finally {
lock.unlock();
}
}
}
public void consume() {
while (true) {
lock.lock();
try {
while (CollectionUtils.isEmpty(list)) {
System.out.println("没有物品了,需要生产了");
produceCondition.signal();
try {
consumerCondition.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName() + "消费产品,共有:" + list.size());
list.remove(0);
} finally {
lock.unlock();
}
}
}
}
生产者线程
public class ProduceThread implements Runnable {
private Resource resource;
public ProduceThread(Resource resource){
this.resource = resource;
}
@Override
public void run() {
resource.produce();
}
}
消费者线程
public class ConsumerThread implements Runnable {
private Resource resource;
public ConsumerThread(Resource resource){
this.resource = resource;
}
@Override
public void run() {
resource.consume();
}
}
测试案例
public class ConditionDemo {
public static void main(String[] args) throws InterruptedException {
Resource resource = new Resource();
ProduceThread produceThread = new ProduceThread(resource);
ConsumerThread consumerThread = new ConsumerThread(resource);
// 4个生产者
for (int i = 0; i < 4; i++) {
new Thread(produceThread).start();
new Thread(consumerThread).start();
}
}
}
原创:做时间的朋友