同样的下面要给大家带来的是一个比较简单的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 foods = new ArrayList ();
// 生产食物的方法
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
{
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()
{
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
{
Food food = foods.remove(foods.size() - 1);
System.out.println("消费了一个" + food.getName() + foods.size());
}
}
}
}
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工具网来了解吧。
推荐阅读: