传统模型
package suanfa;
import java.util.Date;
import java.util.LinkedList;
public class Main {
public static void main(String[] args) throws Exception {
Buffer buffer = new Buffer(5);
for(int i =1;i<=3;i++){
new Thread(new Producer(buffer)).start();
new Thread(new Consumer(buffer)).start();
}
}
}
class Buffer{
int maxSize;
LinkedList<Date> list;
public Buffer(int maxSize){
this.maxSize = maxSize;
list = new LinkedList<Date>();
}
public synchronized void put() throws Exception{
while(list.size() == maxSize){
this.wait();
}
list.push(new Date());
System.out.println(Thread.currentThread().getName()+"生产了商品, 当前商品数:"+list.size());
//唤醒所有消费者
this.notifyAll();
}
public synchronized void take() throws Exception{
//为什么用while?:notifyAll会唤醒全部消费者、生产者线程,唤醒后的执行顺序是随机的,若消费者抢到了执行权
//此时列表数目为0,不能消费,所以继续休眠
while(list.size() == 0){
this.wait();
}
list.pop();
System.out.println(Thread.currentThread().getName()+"消费了商品, 当前商品数:"+list.size());
//唤醒所有生产者
this.notifyAll();
}
}
class Producer implements Runnable{
Buffer buffer;
public Producer(Buffer buffer){
this.buffer = buffer;
}
@Override
public void run() {
while(true){
try {
buffer.put();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
class Consumer implements Runnable{
Buffer buffer;
public Consumer(Buffer buffer){
this.buffer = buffer;
}
@Override
public void run() {
while(true){
try {
buffer.take();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
Lock、Condition模型
package suanfa;
import java.util.Date;
import java.util.LinkedList;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Main {
public static void main(String[] args) throws Exception {
Buffer buffer = new Buffer(5);
for (int i = 1; i <= 3; i++) {
new Thread(new Producer(buffer)).start();
new Thread(new Consumer(buffer)).start();
}
}
}
class Buffer {
int maxSize;
LinkedList<Date> list;
ReentrantLock lock;
//与传统模型的不同之处,以免notifyAll唤醒全部等待线程,抽象两个阻塞队列,这样消费者可以只唤醒全部的生产者,
//生产者也可以只唤醒全部的消费者
Condition producer;
Condition consumer;
public Buffer(int maxSize) {
lock = new ReentrantLock();
this.maxSize = maxSize;
list = new LinkedList<Date>();
producer = lock.newCondition();
consumer = lock.newCondition();
}
public void put() throws Exception {
lock.lock();
try {
while (list.size() == maxSize) {
producer.await();
}
list.push(new Date());
System.out.println(Thread.currentThread().getName() + "生产了商品, 当前商品数:" + list.size());
// 唤醒所有消费者
consumer.signalAll();
} catch (Exception e) {
// TODO: handle exception
}finally {
if(lock.isHeldByCurrentThread()){
lock.unlock();
}
}
}
public void take() throws Exception {
lock.lock();
try {
while (list.size() == 0) {
consumer.await();
}
list.pop();
System.out.println(Thread.currentThread().getName() + "生产了商品, 当前商品数:" + list.size());
// 唤醒所有消费者
producer.signalAll();
} catch (Exception e) {
// TODO: handle exception
}finally {
if(lock.isHeldByCurrentThread()){
lock.unlock();
}
}
}
}
class Producer implements Runnable {
Buffer buffer;
public Producer(Buffer buffer) {
this.buffer = buffer;
}
@Override
public void run() {
while (true) {
try {
buffer.put();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
class Consumer implements Runnable {
Buffer buffer;
public Consumer(Buffer buffer) {
this.buffer = buffer;
}
@Override
public void run() {
while (true) {
try {
buffer.take();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}