同样的下面要给大家带来的是一个比较简单的java多线程实例,在一个KFC当中,服务员负责生产食物,消费者负责消费食物,当生产到了一定数量的时候,就可以休息一下,一直到消费完食物,之后再马上生产,一直循环。
分析:
程序所涉及到的内容-1、java模式思想:生产者消费者模式;2、要保证操作对象的统一性,也就是消费者和服务者都是跟同一个KFC发生关系的,KFC只能new一次;3、this.notifyAll();和 this.wait();一个是所有唤醒的意思,一个是让自己等待的意思(例如在这个题目当中,生产者生产完成之后,先所有唤醒(包括消费者和生产者),再让所有自己(生产者)等待,这个时候的话,消费者开始消费,直到食材不够,先所有唤醒(包括消费者和生产者),再让所有自己(消费者)等待,一直执行上面的操作的循环);4、生产者和消费者都要继承Thread,才可以实现多线程的启动。
思路:
1、创建一个食物类Food,有存放/获取食物的名称的方法
package com.xykj.producer_consumer; public class Food { String name = ""; //通过构造方法传入食物的名字 public Food(String name) { this.name = name; } //get、set 方法 public String getName() { return name; } public void setName(String name) { this.name = name; } }
2、创建一个KFC类,有生产食物和消费食物的方法
package com.xykj.producer_consumer; import java.util.ArrayList; import java.util.List; public class KFC { //食物的种类 String[] names = { "薯条" , "烧板" , "鸡翅" , "可乐" }; //生产的最大值,到达后可以休息 static final int Max = 20; //存放食物的集合 List < food > foods = new ArrayList < food > (); // 生产食物的方法 public void prod(int index) { synchronized(this) { // 如果食物数量大于20 while (foods.size() > Max) { System.out.println("食材够了"); this.notifyAll(); //这个唤醒是针对生产者和消费者,有all try { String name = Thread.currentThread() .getName(); this.wait(); //这个唤醒是针对生产者,没有all System.out.println("生产者:" + name); } catch (InterruptedException e) { e.printStackTrace(); } } // 开始生产食物食物//有一点要注意的 System.out.println("开始生产食物"); for (int i = 0; i < index; i++) { Food food = new Food(names[(int)(Math.random() * 4)]); foods.add(food); System.out.println("生产了" + food.getName() + foods.size()); } } } // 消费食物的方法 public void consu(int index) { synchronized(this) { while (foods.size() < index) { System.out.println("食材不够了"); this.notifyAll(); //这个唤醒是针对生产者和消费者,有all try { String name = Thread.currentThread() .getName(); this.wait(); //这个唤醒是针对消费者,没有all System.out.println("消费者:" + name); } catch (InterruptedException e) { e.printStackTrace(); } } // 足够消费 System.out.println("开始消费"); for (int i = 0; i < index; i++) { Food food = foods.remove(foods.size() - 1); System.out.println("消费了一个" + food.getName() + foods.size()); } } } } </food> < /food>
3、创建一个客户类Customer,继承Thread,重写run方法,在run方法里面进行消费食物操作
package com.xykj.producer_consumer; public class Customers extends Thread { KFC kfc; //KFC要传入,保证每一个服务员和用户在同一个KFC对象内 public Customers(KFC kfc) { this.kfc = kfc; } @Override public void run() { int size = (int)(Math.random() * 5); //每次要消费的食物的数量 while (true) { kfc.consu(size); //在消费的方法里面传入参数 } } }
4、创建一个服务员类Waiter,继承Thread,重写run方法,在run方法里面进行生产食物的操作
package com.xykj.producer_consumer; public class Waiter extends Thread { KFC kfc; //KFC要传入,保证每一个服务员和用户在同一个KFC对象内 public Waiter(KFC kfc) { this.kfc = kfc; } @Override public void run() { int size = (int)(Math.random() * 5) + 5; //每次生产的数量 while (true) { kfc.prod(size); //传入每次生产的数量 } } }
5、创建主方法的调用类
package com.xykj.producer_consumer; public class MainClass { /** * 生产者消费者模式 * * */ public static void main(String[] args) { // 只实例化一个KFC对象,保证每一个服务员和用户在同一个KFC对象内 KFC kfc = new KFC(); //实例化4个客户对象 Customers c1 = new Customers(kfc); Customers c2 = new Customers(kfc); Customers c3 = new Customers(kfc); Customers c4 = new Customers(kfc); //实例化3个服务员对象 Waiter waiter1 = new Waiter(kfc); Waiter waiter2 = new Waiter(kfc); Waiter waiter3 = new Waiter(kfc); //让所有的对象的线程都开始工作 waiter1.start(); waiter2.start(); waiter3.start(); c1.start(); c2.start(); c3.start(); c4.start(); } }
更多java多线程实例,请继续关注奇Q工具网来了解吧。
推荐阅读: