直接看代码吧,log写的很清楚了,重点是在Queue.java类
Consumer用来消费
package com.zhuyang.concurrency.lock.notify;
import java.util.List;
public class Consumer implements Runnable {
private Queue queue;
public Consumer(Queue queue) {
this.queue = queue;
}
@Override
public synchronized void run() {
for (int i = 0; i < 7; i++) {
Product p = new Product();
p.setName("name " + i);
queue.consume(p);
}
}
}
producer用来生产
package com.zhuyang.concurrency.lock.notify;
import java.util.List;
public class Producer implements Runnable {
private Queue queue;
public Producer(Queue queue) {
this.queue = queue;
}
@Override
public synchronized void run() {
for (int i = 0; i < 7; i++) {
Product p = new Product();
p.setName("name " + i);
queue.produce(p);
}
}
}
Product model
package com.zhuyang.concurrency.lock.notify;
public class Product {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Main测试类
package com.zhuyang.concurrency.lock.notify; import java.util.concurrent.Executor; import java.util.concurrent.Executors; public class Main { public static void main(String[] args) { Queue queue=new Queue(); Producer p1=new Producer(queue); Producer p2=new Producer(queue); Producer p3=new Producer(queue); Producer p4=new Producer(queue); Consumer c1=new Consumer(queue); Consumer c2=new Consumer(queue); Consumer c3=new Consumer(queue); Consumer c4=new Consumer(queue); Thread pt1=new Thread(p1); Thread pt2=new Thread(p2); Thread pt3=new Thread(p3); Thread pt4=new Thread(p4); Thread ct1=new Thread(c1); Thread ct2=new Thread(c2); Thread ct3=new Thread(c3); Thread ct4=new Thread(c4); ct1.start(); ct2.start(); ct3.start(); ct4.start(); pt3.start(); pt4.start(); } }
Queue类, 首先用wait notify进行线程通信。package com.zhuyang.concurrency.lock.notify; import java.util.ArrayList; import java.util.List; public class Queue { private List<Product> queue =new ArrayList<Product>(); private int maxCount=5; public synchronized void produce(Product pro){ this.notifyAll(); while(queue.size()==maxCount){//if queue size is 5,then wait for consumer to consume System.err.println(Thread.currentThread().getName()+",product is full,wait,current count is "+getCount()); try { this.wait(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } queue.add(pro); System.out.println(Thread.currentThread().getName()+"we are produce product, current count is "+getCount()); } public synchronized void consume(Product pro){ this.notifyAll(); while(this.queue.size()==0){//if queue is em[ty, then wait for producer to produce System.err.println(Thread.currentThread().getName()+",product is empty,wait,current count is "+getCount()); try { this.wait(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } Product product =queue.get(0); queue.remove(product); System.out.println(Thread.currentThread().getName()+" is consuming ,product name ==="+product.getName()+",current count is "+getCount()); } public synchronized int getCount(){ return queue.size(); } }
使用Lock Condition进行通信
package com.zhuyang.concurrency.lock.lockcondition; import java.util.ArrayList; import java.util.List; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class Queue { private List<Product> queue =new ArrayList<Product>(); private int maxCount=5; private Lock lock =new ReentrantLock(); private Condition producerCon =lock.newCondition(); private Condition consumerCon =lock.newCondition(); public void produce(Product pro){ lock.lock(); try { while(queue.size()==maxCount){ System.err.println(Thread.currentThread().getName()+",product is full,wait,current count is "+getCount()); producerCon.await(); } queue.add(pro); System.out.println(Thread.currentThread().getName()+"we are produce product, current count is "+getCount()); consumerCon.signal(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); }finally{ lock.unlock(); } } public void consume(Product pro){ lock.lock(); try{ while(this.queue.size()==0){ System.err.println(Thread.currentThread().getName()+",product is empty,wait,current count is "+getCount()); consumerCon.await(); } Product product =queue.get(0); queue.remove(product); System.out.println(Thread.currentThread().getName()+" is consuming ,product name ==="+product.getName()+",current count is "+getCount()); producerCon.signal(); }catch(InterruptedException e){ e.printStackTrace(); }finally{ lock.unlock(); } } public int getCount(){ return queue.size(); } }