三种实现方式:
1. Object对象的wait(),notify(),加synchronize.
2. Lock的await(),signal().
3. BlockingQueue阻塞队列.
Object对象的wait(),notify(),加synchronize --> StorageObject();
Lock的await(),signal() --> StorageLock();
BlockingQueue阻塞队列 --> StorageBlockingQueue();
package concurent; import java.util.LinkedList;
import java.util.concurrent.BlockingDeque;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock; /**
* Created by jenkin K on 17/6/8.
*/
public class PCModelTread { public static void main(String args[]){ // Storage storage = new StorageObject();
Storage storage = new StorageLock();
// Storage storage = new StorageBlockingQueue(); Producer p1 = new Producer(storage);
Producer p2 = new Producer(storage);
Producer p3 = new Producer(storage);
Producer p4 = new Producer(storage); Consumer c1 = new Consumer(storage);
Consumer c2 = new Consumer(storage); p1.setNum(6);
p2.setNum(1);
p3.setNum(1);
p4.setNum(8); c1.setNum(1);
c2.setNum(5); new Thread(p1, "producer1").start();
new Thread(p2, "producer2").start();
new Thread(p3, "producer3").start();
new Thread(p4, "producer4").start(); new Thread(c1, "consumer1").start();
new Thread(c2, "consumer2").start();
}
} interface Storage {
public void consume(int num);
public void produce(int num);
} class StorageObject implements Storage {
final int MAX_STORAGE = 10;
private LinkedList<Object> list = new LinkedList<Object>(); public void produce(int num){
synchronized (list){
while(num + list.size() > MAX_STORAGE){
System.out.println("库存:["+ list.size() + "]/["+ MAX_STORAGE +"], 待生产数量:[" + num + "], 生产阻塞:" + Thread.currentThread().getName() + "阻塞.");
try{
list.wait();
}catch (InterruptedException e){
e.printStackTrace();
}
}
for(int i = 0; i < num; i++){
list.add(new Object());
System.out.println("库存:["+ list.size() + "]/[" + MAX_STORAGE + "], " + Thread.currentThread().getName() + "正在生产:[" + (i+1) + "].");
}
System.out.println(Thread.currentThread().getName() + "生产完成, 共生产:" + num + ", 库存:["+ list.size() + "]/["+ MAX_STORAGE +"].");
list.notifyAll();
}
} public void consume(int num){
synchronized (list){
while(list.size() < num){
System.out.println("库存:["+ list.size() + "]/[" + MAX_STORAGE + "], 待消费数量:[" + num + "], 消费阻塞:" + Thread.currentThread().getName() + "阻塞.");
try{
list.wait();
}catch (InterruptedException e){
e.printStackTrace();
}
}
for(int i = 0; i < num; i++){
System.out.println("库存:["+ list.size() + "]/[" + MAX_STORAGE + "], " + Thread.currentThread().getName() + "正在消费:[" + (i+1) + "].");
list.remove();
}
System.out.println(Thread.currentThread().getName() + "消费完成, 共消费:" + num + ", 库存:["+ list.size() + "]/["+ MAX_STORAGE + "].");
list.notifyAll();
}
}
} class StorageLock implements Storage {
final int MAX_STORAGE = 10;
LinkedList<Object> list = new LinkedList<Object>();
Lock lock = new ReentrantLock(false);
Condition produce = lock.newCondition();
Condition consume = lock.newCondition(); @Override
public void produce(int num) {
lock.lock();
try {
while (num + list.size() > MAX_STORAGE) {
System.out.println("库存:[" + list.size() + "]/[" + MAX_STORAGE + "], 待生产数量:[" + num + "], 生产阻塞:" + Thread.currentThread().getName() + "阻塞.");
produce.await();
}
for (int i = 0; i < num; i++) {
list.add(new Object());
System.out.println("库存:[" + list.size() + "]/[" + MAX_STORAGE + "], " + Thread.currentThread().getName() + "正在生产:[" + (i + 1) + "].");
}
System.out.println(Thread.currentThread().getName() + "生产完成, 共生产:" + num + ", 库存:[" + list.size() + "]/[" + MAX_STORAGE + "].");
}catch (InterruptedException e){
e.printStackTrace();
}finally {
produce.signalAll();
consume.signalAll();
lock.unlock();
}
} @Override
public void consume(int num) {
lock.lock();
try {
while (list.size() < num) {
System.out.println("库存:[" + list.size() + "]/[" + MAX_STORAGE + "], 待消费数量:[" + num + "], 消费阻塞:" + Thread.currentThread().getName() + "阻塞.");
consume.await();
}
for (int i = 0; i < num; i++) {
System.out.println("库存:[" + list.size() + "]/[" + MAX_STORAGE + "], " + Thread.currentThread().getName() + "正在消费:[" + (i + 1) + "].");
list.remove();
}
System.out.println(Thread.currentThread().getName() + "消费完成, 共消费:" + num + ", 库存:[" + list.size() + "]/[" + MAX_STORAGE + "].");
}catch (InterruptedException e){
e.printStackTrace();
}finally {
consume.signalAll();
produce.signalAll();
lock.unlock();
}
}
} class StorageBlockingQueue implements Storage{
int MAX_STORAGE = 10;
BlockingQueue<Object> queue = new LinkedBlockingQueue<Object>(MAX_STORAGE); @Override
public void produce(int num) {
if(queue.size() == MAX_STORAGE){
System.out.println("库存:[" + queue.size() + "]/[" + MAX_STORAGE + "], 待生产数量:[" + num + "], 生产阻塞:" + Thread.currentThread().getName() + "阻塞.");
}
for(int i = 0; i < num; i++){
try {
queue.put(new Object());
System.out.println("库存:[" + queue.size() + "]/[" + MAX_STORAGE + "], " + Thread.currentThread().getName() + "正在生产:[" + (i + 1) + "].");
}catch (InterruptedException e){
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName() + "生产完成, 共生产:" + num + ", 库存:[" + queue.size() + "]/[" + MAX_STORAGE + "].");
} @Override
public void consume(int num) {
if(queue.size() == 0){
System.out.println("库存:[" + queue.size() + "]/[" + MAX_STORAGE + "], 待消费数量:[" + num + "], 消费阻塞:" + Thread.currentThread().getName() + "阻塞.");
}
for (int i = 1; i < num; i++){
try{
queue.take();
System.out.println("库存:[" + queue.size() + "]/[" + MAX_STORAGE + "], " + Thread.currentThread().getName() + "正在消费:[" + (i + 1) + "].");
}catch (InterruptedException e){
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName() + "消费完成, 共消费:" + num + ", 库存:[" + queue.size() + "]/[" + MAX_STORAGE + "].");
}
} class Producer implements Runnable { Storage storage;
int num; public Producer(Storage storage){
this.storage = storage;
} @Override
public void run() {
produce(num);
} public void produce(int num){
storage.produce(num);
} public void setNum(int num) {
this.num = num;
}
} class Consumer implements Runnable { Storage storage;
int num; public Consumer(Storage storage){
this.storage = storage;
}
@Override
public void run() {
consumer(num);
} public void consumer(int num){
storage.consume(num);
} public void setNum(int num) {
this.num = num;
}
}
输出结果:
StorageObject()输出结果:
库存:[1]/[10], producer1正在生产:[1].
库存:[2]/[10], producer1正在生产:[2].
库存:[3]/[10], producer1正在生产:[3].
库存:[4]/[10], producer1正在生产:[4].
库存:[5]/[10], producer1正在生产:[5].
库存:[6]/[10], producer1正在生产:[6].
producer1生产完成, 共生产:6, 库存:[6]/[10].
库存:[6]/[10], consumer2正在消费:[1].
库存:[5]/[10], consumer2正在消费:[2].
库存:[4]/[10], consumer2正在消费:[3].
库存:[3]/[10], consumer2正在消费:[4].
库存:[2]/[10], consumer2正在消费:[5].
consumer2消费完成, 共消费:5, 库存:[1]/[10].
库存:[1]/[10], consumer1正在消费:[1].
consumer1消费完成, 共消费:1, 库存:[0]/[10].
库存:[1]/[10], producer4正在生产:[1].
库存:[2]/[10], producer4正在生产:[2].
库存:[3]/[10], producer4正在生产:[3].
库存:[4]/[10], producer4正在生产:[4].
库存:[5]/[10], producer4正在生产:[5].
库存:[6]/[10], producer4正在生产:[6].
库存:[7]/[10], producer4正在生产:[7].
库存:[8]/[10], producer4正在生产:[8].
producer4生产完成, 共生产:8, 库存:[8]/[10].
库存:[9]/[10], producer3正在生产:[1].
producer3生产完成, 共生产:1, 库存:[9]/[10].
库存:[10]/[10], producer2正在生产:[1].
producer2生产完成, 共生产:1, 库存:[10]/[10]. StorageLock()输出结果:
库存:[1]/[10], producer1正在生产:[1].
库存:[2]/[10], producer1正在生产:[2].
库存:[3]/[10], producer1正在生产:[3].
库存:[4]/[10], producer1正在生产:[4].
库存:[5]/[10], producer1正在生产:[5].
库存:[6]/[10], producer1正在生产:[6].
producer1生产完成, 共生产:6, 库存:[6]/[10].
库存:[7]/[10], producer2正在生产:[1].
producer2生产完成, 共生产:1, 库存:[7]/[10].
库存:[8]/[10], producer3正在生产:[1].
producer3生产完成, 共生产:1, 库存:[8]/[10].
库存:[8]/[10], 待生产数量:[8], 生产阻塞:producer4阻塞.
库存:[8]/[10], consumer1正在消费:[1].
consumer1消费完成, 共消费:1, 库存:[7]/[10].
库存:[7]/[10], consumer2正在消费:[1].
库存:[6]/[10], consumer2正在消费:[2].
库存:[5]/[10], consumer2正在消费:[3].
库存:[4]/[10], consumer2正在消费:[4].
库存:[3]/[10], consumer2正在消费:[5].
consumer2消费完成, 共消费:5, 库存:[2]/[10].
库存:[3]/[10], producer4正在生产:[1].
库存:[4]/[10], producer4正在生产:[2].
库存:[5]/[10], producer4正在生产:[3].
库存:[6]/[10], producer4正在生产:[4].
库存:[7]/[10], producer4正在生产:[5].
库存:[8]/[10], producer4正在生产:[6].
库存:[9]/[10], producer4正在生产:[7].
库存:[10]/[10], producer4正在生产:[8].
producer4生产完成, 共生产:8, 库存:[10]/[10]. StorageBlockingQueue()输出结果:
库存:[3]/[10], producer2正在生产:[1].
库存:[3]/[10], consumer2正在消费:[2].
库存:[4]/[10], producer4正在生产:[1].
consumer1消费完成, 共消费:1, 库存:[4]/[10].
库存:[3]/[10], producer3正在生产:[1].
producer3生产完成, 共生产:1, 库存:[3]/[10].
库存:[2]/[10], producer1正在生产:[1].
库存:[3]/[10], producer4正在生产:[2].
库存:[2]/[10], consumer2正在消费:[3].
producer2生产完成, 共生产:1, 库存:[3]/[10].
库存:[4]/[10], consumer2正在消费:[4].
库存:[5]/[10], producer4正在生产:[3].
库存:[4]/[10], producer1正在生产:[2].
库存:[5]/[10], producer1正在生产:[3].
库存:[4]/[10], producer4正在生产:[4].
库存:[3]/[10], consumer2正在消费:[5].
库存:[7]/[10], producer4正在生产:[5].
库存:[6]/[10], producer1正在生产:[4].
库存:[8]/[10], producer4正在生产:[6].
consumer2消费完成, 共消费:5, 库存:[7]/[10].
库存:[10]/[10], producer4正在生产:[7].
库存:[9]/[10], producer1正在生产:[5].
从输出结果看,Synchronized和Lock方式,生产和消费是有序的,也就是某一生产线程全生产完,才会释放锁,不会被其他线程强占。BlockingQueue方式,生产和消费是无序的,即,生产线程没有生产完,或是消费线程没有消费完,都会被其他线程强占。原因是,前者的循环生产操作是在锁同步块里边,后者的生产循环生产操作是在锁的外面。