案例场景如下:
某工厂生产某种产品,有甲、乙销售员负责销售产品。每件产品都有自己的编号,工厂生产某种产品所需要的时间单位分别为1;销售人员每人每3个时间单位销售2件产品。生产与销售的协调关系如下:当商品库存大于100 件时工厂停止生产该产品,当产品库存小于5件时候停止销售,模拟该过程。
1、创建工程。
2、使用notify和wait 技术处理线程同步问题
3、使用队列技术存放产品
4、正确的使用 锁
5、能最终计算30时间单位内的销售冠军
仓库类
package com.itguo.sell;
import java.util.LinkedList;
/**
* 存放产品的仓库
* 生产的方法in()、销售的方法out()
* @author ShuaiGUO
*/
public class WareHouse {
//使用队列,用于存放产品的容器
private LinkedList<Phone> linkedList;
//销售员1的销售次数
private int count1;
//销售员2的销售次数
private int count2;
public LinkedList<Phone> getLinkedList() {
return linkedList;
}
public void setLinkedList(LinkedList<Phone> linkedList) {
this.linkedList = linkedList;
}
public int getCount1() {
return count1;
}
public void setCount1(int count1) {
this.count1 = count1;
}
public int getCount2() {
return count2;
}
public void setCount2(int count2) {
this.count2 = count2;
}
public WareHouse(LinkedList<Phone> linkedList) {
this.linkedList = linkedList;
}
/**
* 生产的方法
*/
public synchronized void in(){
if (this.linkedList.size() > 100){
//当存库大于100件时需要让生产者线程等待
try {
//仓库对象为共享对象,this是它本身
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}else {
//创建产品对象
Phone phone = new Phone("手机");
//把产品对象存放到容器,offer()入队列的方法
this.linkedList.offer(phone);
System.out.println(Thread.currentThread().getName()+" 生产了一个产品 "+phone);
//当库存大于5件的时候唤醒消费者消费
if (this.linkedList.size() > 5){
//唤醒消费者消费
this.notifyAll();
}
}
}
/**
* 销售的方法
*/
public synchronized void out(){
//当库存小于5件时,消费者不能消费
if (this.linkedList.size() < 5){
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}else {
//判断哪个线程执行了out方法
//getClass(),获取线程的字节码对象
if (Thread.currentThread().getClass() == Sell01.class){
count1++;
}else {
count2++;
}
//poll()出队列的方法
Phone phone = this.linkedList.poll();
System.out.println(Thread.currentThread().getName()+" 销售了一个产品 "+phone);
//唤醒消费者消费
this.notifyAll();
}
}
}
销售员1
package com.itguo.sell;
/**
* 销售员1
* @author ShuaiGUO
*/
public class Sell01 extends Thread{
private String name;
private WareHouse wareHouse;
public Sell01(String name, WareHouse wareHouse) {
super(name);
this.name = name;
this.wareHouse = wareHouse;
}
@Override
public void run() {
for (int i = 0; i < 10; i++) {
//调用销售的方法
this.wareHouse.out();
this.wareHouse.out();
try {
//模拟三个时间单位
Thread.sleep(500*3);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
销售员2
package com.itguo.sell;
/**
* 销售员2
* @author ShuaiGUO
*/
public class Sell02 extends Thread{
private String name;
private WareHouse wareHouse;
public Sell02(String name, WareHouse wareHouse) {
super(name);
this.name = name;
this.wareHouse = wareHouse;
}
@Override
public void run() {
for (int i = 0; i < 10; i++) {
//调用销售的方法
this.wareHouse.out();
this.wareHouse.out();
try {
//模拟三个时间单位
Thread.sleep(500*3);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
生产厂家
package com.itguo.sell;
/**
* 生产者线程
* @author ShuaiGUO
*/
public class Producer extends Thread{
private Sell01 sell01;
private Sell02 sell02;
private WareHouse wareHouse;
private String name;
public Producer(Sell01 sell01, Sell02 sell02, WareHouse wareHouse, String name) {
//设置线程名称
super(name);
this.sell01 = sell01;
this.sell02 = sell02;
this.wareHouse = wareHouse;
this.name = name;
}
@Override
public void run() {
//模拟一个一直生产的过程
while (true){
//调用生产的方法
this.wareHouse.in();
//模拟一个时间单位为500毫秒
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
//结束循环的条件
if (!sell01.isAlive()&&!sell02.isAlive()){
break;
}
}
}
}
产品类
package com.itguo.sell;
/**
* 产品类
* @author ShuaiGUO
*/
public class Phone {
//产品名称
private String phoneName;
//产品编号
private int id;
//设置编号默认值
private static int no = 1000;
public Phone(String phoneName) {
this.phoneName = phoneName;
//每次创建一个对象,使no的值加一
this.id = no++;
;
}
public Phone() {
//每次创建一个对象,使no的值加一
this.id = no++;
}
public String getPhoneName() {
return phoneName;
}
public void setPhoneName(String phoneName) {
this.phoneName = phoneName;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public static int getNo() {
return no;
}
public static void setNo(int no) {
Phone.no = no;
}
@Override
public String toString() {
return "Phone{" +
"phoneName='" + phoneName + '\'' +
", id=" + id +
'}';
}
}
测试类
package com.itguo.sell;
import java.util.LinkedList;
/**
* @author ShuaiGUO
*/
public class Test {
public static void main(String[] args) {
//创建仓库对象
WareHouse wareHouse = new WareHouse(new LinkedList<Phone>());
//创建销售员1线程
Sell01 sell01 = new Sell01("销售员1",wareHouse);
//创建销售员2线程
Sell02 sell02 = new Sell02("销售员2",wareHouse);
//创建生产者线程
Producer producer = new Producer(sell01, sell02, wareHouse, "产品厂家");
//开启线程
sell01.start();
sell02.start();
producer.start();
//合并线程
try {
sell01.join();
sell02.join();
producer.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(sell01.getName()+"销售了"+wareHouse.getCount1());
System.out.println(sell02.getName()+"销售了"+wareHouse.getCount2());
if (wareHouse.getCount1() > wareHouse.getCount2()){
System.out.println(sell01.getName()+"是销售冠军");
}else {
System.out.println(sell02.getName()+"是销售冠军");
}
}
}