java多线程之生产者与消费者模型2
在java5中加入了并发包,里面有很多有关并发相关的工具类,其中Lock 就是实现提供比使用synchronized方法和代码块获得更加广泛的锁定操作。这样会有更加灵活的结构,可以具有差别很大的属性,可以支持多个Condition对象。那么什么是Condition是什么呢?Condition是将Object监视器方法 wait、notify、notifyAll 分解成截然不同的对象,以便通过这些对象与Lock实现组合使用。那我们可以看出 Lock 代替了 synchronized 方法和代码块的使用,Condition代替了Object监视器方法的使用。在使用Condition的实例的时候会被绑定到一个锁上 ,所有我们要为特定的Lock获取Condition实例,我们使用Lock.newCondition 方法获取Condition。Condition的方法 await 造成当前线程在接到singal 或者singnalAll方法唤醒之前或一直处于等待状态。
在大多数我们使用锁的时候应该使用一下格式:
Lock l = ...;
l.lock();
try {
// access the resource protected by this lock
} finally {
l.unlock();
}
具体使用方法请看案例:
package java5.lock;
import java.util.Queue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class LockTest {
private static Lock lock = new ReentrantLock();
private static Condition isFullCondition = lock.newCondition();
private static Condition isEmptyCondition = lock.newCondition();
private static Queue<Apple> queue = new LinkedBlockingQueue<LockTest.Apple>();
private static class Apple {
private String name;
public Apple(String name) {
super();
this.name = name;
}
@Override
public String toString() {
return "Apple [name=" + name + "]";
}
}
/**
* 消费者
* @author gaoyuandong
* @date 2015年7月24日 下午10:14:44
* @mail 466862016@qq.com
*/
private static class Customer extends Thread {
@Override
public void run() {
while (true) {
lock.lock();
try {
if (queue.size() <=0) {
System.err.println(Thread.currentThread().getName() +" 我饿,没有东西吃了,我等待...");
isEmptyCondition.await();
}
queue.poll();
System.err.println( Thread.currentThread().getName() +" 我吃了一个苹果 还剩下" +queue.size() +"个苹果");
isFullCondition.signalAll();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally{
lock.unlock();
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
/**
* 生产者
* @author gaoyuandong
* @date 2015年7月24日 下午10:13:53
* @mail 466862016@qq.com
*/
private static class Producer extends Thread {
@Override
public void run() {
while (true) {
lock.lock();
try {
if(queue.size() >= 30) {
System.err.println(Thread.currentThread().getName() +" 我是生产者,我生产够了苹果。我要等待....");
isFullCondition.await();
}
queue.add(new Apple("xx"));
System.err.println(Thread.currentThread().getName() +" 我是生产者,我新生产一个苹果 现在共有" + queue.size() +"个苹果");
isEmptyCondition.signalAll();
} catch (Exception e) {
// TODO: handle exception
}finally {
lock.unlock();
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
public static void main(String[] args) {
Producer producer = new Producer();
producer.start();
for (int i = 0; i < 10; i++) {
Customer customer = new Customer();
customer.start();
}
}
}
输出结果:
Thread-0 我是生产者,我新生产一个苹果 现在共有1个苹果
Thread-2 我吃了一个苹果 还剩下0个苹果
Thread-3 我饿,没有东西吃了,我等待...
Thread-1 我饿,没有东西吃了,我等待...
Thread-4 我饿,没有东西吃了,我等待...
Thread-6 我饿,没有东西吃了,我等待...
Thread-5 我饿,没有东西吃了,我等待...
Thread-7 我饿,没有东西吃了,我等待...
Thread-8 我饿,没有东西吃了,我等待...
Thread-9 我饿,没有东西吃了,我等待...
Thread-10 我饿,没有东西吃了,我等待...
Thread-2 我饿,没有东西吃了,我等待...
Thread-0 我是生产者,我新生产一个苹果 现在共有1个苹果
Thread-3 我吃了一个苹果 还剩下0个苹果
Thread-1 我吃了一个苹果 还剩下0个苹果
Thread-4 我吃了一个苹果 还剩下0个苹果
Thread-6 我吃了一个苹果 还剩下0个苹果
Thread-5 我吃了一个苹果 还剩下0个苹果
Thread-7 我吃了一个苹果 还剩下0个苹果
Thread-8 我吃了一个苹果 还剩下0个苹果
Thread-9 我吃了一个苹果 还剩下0个苹果
Thread-10 我吃了一个苹果 还剩下0个苹果
Thread-2 我吃了一个苹果 还剩下0个苹果
Thread-0 我是生产者,我新生产一个苹果 现在共有1个苹果
Thread-9 我吃了一个苹果 还剩下0个苹果
Thread-6 我饿,没有东西吃了,我等待...
Thread-7 我饿,没有东西吃了,我等待...
Thread-2 我饿,没有东西吃了,我等待...
Thread-3 我饿,没有东西吃了,我等待...
Thread-10 我饿,没有东西吃了,我等待...
Thread-1 我饿,没有东西吃了,我等待...
Thread-4 我饿,没有东西吃了,我等待...
Thread-5 我饿,没有东西吃了,我等待...
Thread-8 我饿,没有东西吃了,我等待...
Thread-9 我饿,没有东西吃了,我等待...
Thread-0 我是生产者,我新生产一个苹果 现在共有1个苹果
Thread-6 我吃了一个苹果 还剩下0个苹果
Thread-7 我吃了一个苹果 还剩下0个苹果
Thread-2 我吃了一个苹果 还剩下0个苹果
Thread-3 我吃了一个苹果 还剩下0个苹果
Thread-10 我吃了一个苹果 还剩下0个苹果
Thread-1 我吃了一个苹果 还剩下0个苹果
Thread-4 我吃了一个苹果 还剩下0个苹果
Thread-5 我吃了一个苹果 还剩下0个苹果
Thread-8 我吃了一个苹果 还剩下0个苹果
Thread-9 我吃了一个苹果 还剩下0个苹果
Thread-0 我是生产者,我新生产一个苹果 现在共有1个苹果
Thread-9 我吃了一个苹果 还剩下0个苹果
Thread-7 我饿,没有东西吃了,我等待...
Thread-3 我饿,没有东西吃了,我等待...
Thread-6 我饿,没有东西吃了,我等待...
Thread-2 我饿,没有东西吃了,我等待...
Thread-10 我饿,没有东西吃了,我等待...
Thread-5 我饿,没有东西吃了,我等待...
Thread-1 我饿,没有东西吃了,我等待...
Thread-4 我饿,没有东西吃了,我等待...
Thread-8 我饿,没有东西吃了,我等待...
Thread-9 我饿,没有东西吃了,我等待...
Thread-0 我是生产者,我新生产一个苹果 现在共有1个苹果
Thread-7 我吃了一个苹果 还剩下0个苹果
Thread-3 我吃了一个苹果 还剩下0个苹果
Thread-6 我吃了一个苹果 还剩下0个苹果
Thread-2 我吃了一个苹果 还剩下0个苹果
Thread-10 我吃了一个苹果 还剩下0个苹果
Thread-5 我吃了一个苹果 还剩下0个苹果
Thread-1 我吃了一个苹果 还剩下0个苹果
Thread-4 我吃了一个苹果 还剩下0个苹果
Thread-8 我吃了一个苹果 还剩下0个苹果
Thread-9 我吃了一个苹果 还剩下0个苹果
Thread-5 我饿,没有东西吃了,我等待...
Thread-1 我饿,没有东西吃了,我等待...
Thread-4 我饿,没有东西吃了,我等待...
Thread-8 我饿,没有东西吃了,我等待...
Thread-7 我饿,没有东西吃了,我等待...
Thread-3 我饿,没有东西吃了,我等待...
Thread-6 我饿,没有东西吃了,我等待...
Thread-2 我饿,没有东西吃了,我等待...
Thread-10 我饿,没有东西吃了,我等待...
Thread-9 我饿,没有东西吃了,我等待...
Thread-0 我是生产者,我新生产一个苹果 现在共有1个苹果
Thread-5 我吃了一个苹果 还剩下0个苹果
Thread-1 我吃了一个苹果 还剩下0个苹果
Thread-4 我吃了一个苹果 还剩下0个苹果
Thread-8 我吃了一个苹果 还剩下0个苹果
Thread-7 我吃了一个苹果 还剩下0个苹果
Thread-3 我吃了一个苹果 还剩下0个苹果
Thread-6 我吃了一个苹果 还剩下0个苹果
Thread-2 我吃了一个苹果 还剩下0个苹果
Thread-10 我吃了一个苹果 还剩下0个苹果
Thread-9 我吃了一个苹果 还剩下0个苹果
Thread-7 我饿,没有东西吃了,我等待...
Thread-5 我饿,没有东西吃了,我等待...
Thread-4 我饿,没有东西吃了,我等待...
Thread-0 我是生产者,我新生产一个苹果 现在共有1个苹果
Thread-1 我吃了一个苹果 还剩下0个苹果
Thread-8 我饿,没有东西吃了,我等待...
Thread-9 我饿,没有东西吃了,我等待...
Thread-6 我饿,没有东西吃了,我等待...
Thread-10 我饿,没有东西吃了,我等待...
Thread-3 我饿,没有东西吃了,我等待...
Thread-2 我饿,没有东西吃了,我等待...
Thread-7 我吃了一个苹果 还剩下0个苹果
Thread-5 我吃了一个苹果 还剩下0个苹果
Thread-4 我吃了一个苹果 还剩下0个苹果