大学生水果预定配送网站建设的项目规划书,wordpress 4.4.1 中文,会计网站模板,画画外包网站1.案例描述
这里以吃饭为例#xff0c;假设有一个桌子#xff0c;用来存汉堡包#xff0c;然后有厨师和消费者#xff0c;厨师往桌子上放汉堡包#xff0c;消费者从桌子上取走汉堡包。当两者在一个时间段同时进行多次自己的操作时#xff0c;很明显这就是多线程编程的生…1.案例描述
这里以吃饭为例假设有一个桌子用来存汉堡包然后有厨师和消费者厨师往桌子上放汉堡包消费者从桌子上取走汉堡包。当两者在一个时间段同时进行多次自己的操作时很明显这就是多线程编程的生产者消费者实例了。在这里我们希望厨师每次生产一个汉堡包消费者就拿走一个汉堡包如果汉堡包还没有被取走那么厨师应该等待而如果桌子上没有汉堡包则消费者应该等待。
2.案例分析
厨师类Cooker实现Runnable接口【通用】包含放汉堡包的方法 消费者类Foodie实现Runnable接口【通用】包含拿汉堡包的方法 桌子类Desk共享数据 生产者消费者线程套路: //1. while(true)死循环 //2. synchronized锁,锁对象要唯一 //3判断,共享数据是否结束[true]结束 //4判断,共享数据是否结束[false]没有结束
测试类Demo1测试类按如下步骤实现这个案例 1 创建桌子对象作为共享数据区域 2 创建厨师线程把桌子对象作为参数传递至构造方法【需创建对应的桌子对象成员变量】因为厨师需要完成放汉堡包的操作 3创建消费者线程把桌子对象作为对象传递至构造方法【需创建对应的桌子对象成员变量】因为消费者需要完成拿汉堡包的操作 4启动线程
3.代码实现
1等待唤醒实现 wait(); 【等待】 notifyAll() 【叫醒等待的所有线程】
public class Demo1 {public static void main(String[] args) {Desk desk new Desk();Foodie foodie new Foodie(desk);foodie.start();Cooker cooker new Cooker(desk);cooker.start();}
}//厨师类
public class Cooker extends Thread {private Desk desk;public Cooker(Desk desk) {this.desk desk;}Overridepublic void run() {//生产者步骤:while (true) {//同步代码块synchronized (desk.getLock()) {//判断汉堡包的数量是否达到if (desk.getCount() 0) {break;} else {//1判断桌子上是否有汉堡包if (!desk.isFlag()) {//3.如果没有才生产System.out.println(生产者生产汉堡包);// 把汉堡包放在桌上desk.setFlag(true);//叫醒等待的消费者开吃desk.getLock().notifyAll();} else {//2.如果有就等待try {//使用什么对象当做锁,那么就必须用这个对象去调用等待和唤醒的方法desk.getLock().wait();} catch (InterruptedException e) {e.printStackTrace();}}}}}}
}//消费者类
public class Foodie extends Thread {private Desk desk;public Foodie(Desk desk) {this.desk desk;}//消费者步骤:Overridepublic void run() {while (true) {//同步代码块synchronized (desk.getLock()) {//判断汉堡包的数量if (desk.getCount() 0) {break;} else { //1判断桌子上是否有汉堡包if (desk.isFlag()) {//3如果有就开吃System.out.println(吃货吃汉堡包);//4吃完之后桌子上的汉堡包就没有了//叫醒等待的生产者继续生产汉堡包的总数量减一desk.setCount(desk.getCount() - 1);desk.setFlag(false);desk.getLock().notifyAll();//叫醒等待的所有线程[把生产者唤醒]} else {//2如果没有就等待//没有就等待[释放锁再等待]//使用什么对象当做锁,那么就必须用这个对象去调用等待和唤醒的方法try {desk.getLock().wait();} catch (InterruptedException e) {e.printStackTrace();}}}}}}
}//桌子类
public class Desk {//定义一个标记//true表示有,false表示没有汉堡包//public static boolean flag;private boolean flag;//定义一个汉堡包数,表示消费几个结束//public static int count 10;private int count;//定义一个锁对象 用于消费者线程和生产者线程用同一把锁//public static final Object lock new Object();private final Object lock new Object();public Desk(boolean flag, int count) {this.flag flag;this.count count;}public Desk() {//无参构造可用于初始化赋值this(false,3);}public boolean isFlag() {return flag;}public void setFlag(boolean flag) {this.flag flag;}public int getCount() {return count;}public void setCount(int count) {this.count count;}public Object getLock() {return lock;}
}打印结果
----------------------------------------------------------------------
生产者生产汉堡包
吃货吃汉堡包
生产者生产汉堡包
吃货吃汉堡包
生产者生产汉堡包
吃货吃汉堡包
2阻塞队列实现 创建阻塞队列实现对象,泛型为String[汉堡包],capacity[队列限量]–1[生产一个拿一个] 原理阻塞队列的put和take方法内部有锁
//测试类
public class Demo1 {public static void main(String[] args) {//创建阻塞队列实现对象,泛型为String[汉堡包],capacity[队列限量]--1[生产一个拿一个]ArrayBlockingQueueString list new ArrayBlockingQueueString(1);Cooker cooker new Cooker(list);Foodie foodie new Foodie(list);new Thread(cooker).start();new Thread(foodie).start();//由于阻塞队列的put和take方法内部有锁// 而我们加上的打印语句不在锁内所以打印出来不均匀}
}//厨师类
public class Cooker extends Desk implements Runnable {private ArrayBlockingQueueString list;public Cooker(ArrayBlockingQueueString list) {this.list list;}Overridepublic void run() {while (true){//判断汉堡数if(Desk.count0){break;}//队列没有则生产try {list.put(汉堡包);//添加元素添加满了则等待System.out.println(生产者生产了一个汉堡包);} catch (InterruptedException e) {e.printStackTrace();}}}
}//消费者类
public class Foodie extends Desk implements Runnable {private ArrayBlockingQueueString list;public Foodie(ArrayBlockingQueueString list) {this.list list;}Overridepublic void run() {while (true) {//判断汉堡数if(Desk.count0){break;}//队列有则取出try {String s list.take();//取出元素取完了则等待Desk.count--;System.out.println(消费者拿出了 s);} catch (InterruptedException e) {e.printStackTrace();}}}
}//桌子类
public class Desk {static int count 3;
}打印结果
----------------------------------------------------------------------
生产者生产了一个汉堡包
生产者生产了一个汉堡包
消费者拿出了汉堡包
消费者拿出了汉堡包
生产者生产了一个汉堡包
消费者拿出了汉堡包注【因为阻塞队列有锁锁会强制线程获取最新共享数据则不会出现共享数据问题】 【阻塞队列的锁在内部我们加上的打印语句不在锁内所以打印出来不均匀】