Lock与Condition
java5.0新特性:让一个锁上可以关联多个监视器对象
单独为生产者创建一个监视器对象,单独为消费者创建一个监视器对象
同一个锁有2组监视器,分别用来监视生产者与消费者
解决了唤醒本方线程的问题,而且等待与唤醒的目标更加清晰!
lock替代了synchronized
await()替代了wait()
signal()替代了notify()
signalAll()替代了notifyAll()
释放锁的动作一定要放在finally中,确保任何情况下锁都会被释放
资源
package com.gc.thread.producer;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Resource{
private String name;//资源
private int No;//资源编号
boolean flag = false;//仓库是否有资源
//唯一的锁
Lock lock = new ReentrantLock();
//分别为生产者与消费者各自独立分配一个监视器对象(这些监视器对象都绑定在同一把锁上)
//1.通过锁获取生产者监视器对象
Condition producerCon = lock.newCondition();
//2.通过锁获取消费者监视器对象
Condition consumerCon = lock.newCondition();
/**
* 生产者
* @param name
* @throws InterruptedException
*/
public synchronized void produce(String name) throws InterruptedException {
lock.lock();
try {
while(flag)
producerCon.await();//调用生产者监视器对象的await(),让当前的生产者线程等待
//为商品编号
this.name = name + (++No);
//生产1个商品
System.out.println(Thread.currentThread().getName()+"--->生产:" + this.name);
//更新标记
this.flag = true;
consumerCon.signal();//调用消费者监视器对象的signal(),唤醒处于等待状态的消费者线程
} finally {
lock.unlock();//释放锁
}
}
/**
* 消费者
* @throws InterruptedException
*/
public synchronized void consume() throws InterruptedException {
lock.lock();
try {
while(!flag)
consumerCon.await();//调用消费者监视器对象的await(),让当前的消费者线程等待
//消费1个商品
System.out.println(Thread.currentThread().getName()+"------>消费:" + this.name);
//更新标记
this.flag = false;
producerCon.signal();//调用生产者监视器对象的signal(),唤醒处于等待状态的生产者线程
} finally {
lock.unlock();//释放锁
}
}
}
生产者
package com.gc.thread.producer;
public class Producer implements Runnable {
private Resource r;
public Producer(Resource r) {
this.r = r;
}
@Override
public void run() {
while(true)
try {
r.produce("goods");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
消费者
package com.gc.thread.producer;
public class Consumer implements Runnable {
private Resource r;
public Consumer(Resource r) {
this.r = r;
}
@Override
public void run() {
while(true)
try {
r.consume();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
开启线程
package com.gc.thread.producer;
public class Demo {
public static void main(String[] args) {
//资源
Resource r = new Resource();
//生产者
Producer producer1 = new Producer(r);
Producer producer2 = new Producer(r);
//消费者
Consumer consumer1 = new Consumer(r);
Consumer consumer2 = new Consumer(r);
new Thread(producer1).start();
new Thread(producer2).start();
new Thread(consumer1).start();
new Thread(consumer2).start();
}
}