KFC中,同时有多个产者生产汉堡,也有多个消费者消费汉堡,当生产到100个剩余时,就暂停生产;当销售到0个时,就暂停销售。此例子就是简单的多生产和多消费问题,跟有些多生产多消费例子不同的是其他的基本上是生产一个汉堡就唤醒消费者消费,生成一个消费一个;而在本例子中生产者和消费者则互不影响,只是达到设置的极限条件之后才唤醒。
本例子使用了三种实现方式,分别为简单多线程实现、用线程池实现、用jdk1.5新特性Lock和Condition实现。
1、简单多线程实现
package com.shone.thread.KFC;
/**
* Created by Xiao GuoJian on 2018/1/24.
* 在一个KFC内,服务员负责生产食物,消费者负责消费食物;
* 当生产到一定数量可以休息一下,直到消费完食物,再马上生产,一直循环
*/
class Food{
public int count = 1;//默认数量
public int maxCount = 20;//count为100时,生产者停止生产
//生产
public synchronized void product(){
while(count>=maxCount){
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
count++;
try {
Thread.sleep(25);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+" 生产一个汉堡,当前汉堡数:"+count);
if(count == maxCount){
notifyAll();
}
}
//消费
public synchronized void consume(){
while(count <= 0){
try {
wait();//当前线程等待
} catch (InterruptedException e) {
e.printStackTrace();
}
}
count--;
try {
Thread.sleep(20);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+" 消费一个汉堡,当前汉堡数:"+count);
if(count==0){
notifyAll();
}
}
}
//生产者
class Producter extends Thread{
private Food food;
public Producter(Food food){
super();
this.food = food;
}
public void run(){
while (true){
food.product();
}
}
}
//消费者
class Consumer extends Thread{
private Food food;
public Consumer(Food food){
super();
this.food = food;
}
public void run(){
while (true){
food.consume();
}
}
}
public class KfcDemo {
public static void main(String[] args) {
Food food = new Food();
Producter producter1 = new Producter(food);
Producter producter2 = new Producter(food);
Consumer consumer1 = new Consumer(food);
Consumer consumer2 = new Consumer(food);
producter1.start();
producter2.start();
consumer1.start();
consumer2.start();
}
}
2、用线程池实现
package com.shone.thread.KFCwithPool;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* Created by Xiao GuoJian on 2018/1/24.
* 在一个KFC内,服务员负责生产食物,消费者负责消费食物;
* 当生产到一定数量可以休息一下,直到消费完食物,再马上生产,一直循环
*
* 用线程池的方式实现多生产多消费
*/
class Food{
public int count = 1;//默认数量
public int maxCount = 20;//count为100时,生产者停止生产
//生产
public synchronized void product(){
while(count>=maxCount){
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
count++;
try {
Thread.sleep(25);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+" 生产一个汉堡,当前汉堡数:"+count);
if(count == maxCount){
notifyAll();
}
}
//消费
public synchronized void consume(){
while(count <= 0){
try {
wait();//当前线程等待
} catch (InterruptedException e) {
e.printStackTrace();
}
}
count--;
try {
Thread.sleep(20);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+" 消费一个汉堡,当前汉堡数:"+count);
if(count==0){
notifyAll();
}
}
}
//生产者
class Producter implements Runnable{
private Food food;
public Producter(Food food){
super();
this.food = food;
}
public void run(){
while (true){
food.product();
}
}
}
//消费者
class Consumer implements Runnable{
private Food food;
public Consumer(Food food){
super();
this.food = food;
}
public void run(){
while (true){
food.consume();
}
}
}
public class KfcDemo {
public static void main(String[] args) {
Food food = new Food();
Producter producter1 = new Producter(food);
Producter producter2 = new Producter(food);
Consumer consumer1 = new Consumer(food);
Consumer consumer2 = new Consumer(food);
ExecutorService pool = Executors.newCachedThreadPool();
pool.execute(producter1);
pool.execute(producter2);
pool.execute(consumer1);
pool.execute(consumer2);
}
}
3、用jdk1.5新特性Lock和Condition实现
package com.shone.thread.KFCLock;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* Created by Xiao GuoJian on 2018/1/24.
* 在一个KFC内,服务员负责生产食物,消费者负责消费食物;
* 当生产到一定数量可以休息一下,直到消费完食物,再马上生产,一直循环
*
* 用Lock 和 Condition实现
* 这样的好处是更灵活,可以分开控制是生产者和消费者
*/
class Food{
public int count = 1;//默认数量
public int maxCount = 20;//count为100时,生产者停止生产
Lock lock = new ReentrantLock();//创建锁
Condition pro_ = lock.newCondition();//生产者锁条件(监视器)对象
Condition con_ = lock.newCondition();//消费者锁条件(监视器)对象
//生产
public void product(){
lock.lock();//获得锁
try{
while(count>=maxCount){
try {
pro_.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
count++;
try {
Thread.sleep(25);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+" 生产一个汉堡,当前汉堡数:"+count);
if(count == maxCount){
con_.signalAll();
}
} finally {
lock.unlock();
}
}
//消费
public void consume(){
lock.lock();
try{
while(count <= 0){
try {
con_.await();//当前线程等待
} catch (InterruptedException e) {
e.printStackTrace();
}
}
count--;
try {
Thread.sleep(20);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+" 消费一个汉堡,当前汉堡数:"+count);
if(count==0){
pro_.signalAll();
}
} finally {
lock.unlock();
}
}
}
//生产者
class Producter extends Thread{
private Food food;
public Producter(Food food){
super();
this.food = food;
}
public void run(){
while (true){
food.product();
}
}
}
//消费者
class Consumer extends Thread{
private Food food;
public Consumer(Food food){
super();
this.food = food;
}
public void run(){
while (true){
food.consume();
}
}
}
public class KfcDemo {
public static void main(String[] args) {
Food food = new Food();
Producter producter1 = new Producter(food);
Producter producter2 = new Producter(food);
Consumer consumer1 = new Consumer(food);
Consumer consumer2 = new Consumer(food);
producter1.start();
producter2.start();
consumer1.start();
consumer2.start();
}
}