案例介绍:
某工厂生产某种产品,有甲、乙销售员负责销售产品。每件产品都有自己的编号。
工厂生产某种产品所需的时间单位为1,销售人员每3个时间单位销售2件商品,生产与销售的协调关系如下:
当商品库存大于100件时工厂停止生产该商品,当产品库存小于5件时候停止销售,模拟该过程。
1.创建工程
2.使用notify和wait处理线程同步问题
3.使用队列技术存放产品
4.正确的使用锁
5.能最终统计30时间单位内的销售冠军。
设置生产者worker,仓库storage,消费者sell1与sell2,产品phone,测试类Test
phone
/**
* 产品
*/
public class Phone {
//编号
private int id;
private String name;
private static int no = 1;
public Phone(String name) {
this.id = no++;
this.name = name;
}
public Phone() {
this.id = no++;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public static int getNo() {
return no;
}
public static void setNo(int no) {
Phone.no = no;
}
@Override
public String toString() {
return "Phone{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
}
worker
/**
* 生产者
* @author
*/
public class Worker extends Thread{
private Storage storage;
private Sell1 sell1;
private Sell2 sell2;
public Worker(Storage storage, Sell1 sell1, Sell2 sell2,String name) {
super(name);
this.storage = storage;
this.sell1 = sell1;
this.sell2 = sell2;
}
@Override
public void run() {
while(true){
//调用生产的方法
storage.in();
try {
//100ms为一个时间单位
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
//如果两个销售员线程都结束了,就结束生产者线程
if(!this.sell1.isAlive() && !this.sell2.isAlive()){
break;
}
}
}
}
storage
/**
* 共享的仓库对象
*/
public class Storage {
/**
* 队列进行入库处理
*/
private LinkedList<Phone> linkedList;
/**
* 销售员1的产品计数
*/
private int count1 = 0;
/**
* 销售员2的产品计数
*/
private int count2 = 0;
public LinkedList<Phone> getLinkedList() {
return linkedList;
}
public int getCount1() {
return count1;
}
public int getCount2() {
return count2;
}
public Storage(LinkedList<Phone> linkedList) {
this.linkedList = linkedList;
}
/**
* 生产者调用的方法:入库
*/
public synchronized void in(){
if(this.getLinkedList().size()>100){
try {
//生产者线程进入等待池
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}else {
Phone phone = new Phone("荣耀");
//存入队列,先进先出,offer是入队方法
linkedList.offer(phone);
System.out.println(Thread.currentThread().getName()+"生产了"+phone.getName()+",产品编号为"+phone.getId()+"库存数量为"+this.getLinkedList().size());
//如果库存大于五件,就可以唤醒消费者进行消费
if(this.getLinkedList().size()>5){
notifyAll();
}
}
}
/**
* 消费者调用的方法:出库
*/
public synchronized void out() {
if (this.getLinkedList().size() < 5) {
try {
//消费者线程进入等待池
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}else{
//对比字节码文件,判断是哪个销售员线程
if(Thread.currentThread().getClass() == Sell1.class){
count1++;
}else {
count2++;
}
//出队的方法
Phone poll = linkedList.poll();
System.out.println(Thread.currentThread().getName()+"出售了"+poll.getName()+",产品编号为"+poll.getId()+"库存数量为"+this.getLinkedList().size());
//唤醒等待池的线程
notifyAll();
}
}
}
sell1
public class Sell1 extends Thread{
private Storage storage;
public Sell1(Storage storage,String name) {
super(name);
this.storage = storage;
}
@Override
public void run() {
for (int i = 1;i <= 10;i++){
storage.out();
storage.out();
try {
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName()+"销售的产品数量为:"+storage.getCount1());
}
}
sell2
public class Sell2 extends Thread{
private Storage storage;
public Sell2(Storage storage,String name) {
super(name);
this.storage = storage;
}
@Override
public void run() {
for (int i = 1;i <= 10;i++){
storage.out();
storage.out();
try {
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName()+"销售的产品数量为:"+storage.getCount2());
}
}
Test
public class Test {
public static void main(String[] args) {
//创建仓库对象
Storage storage = new Storage(new LinkedList<Phone>());
//创建销售员线程
Sell1 sell1 = new Sell1(storage,"小崔");
Sell2 sell2 = new Sell2(storage, "肥总");
//创建生产者线程
Worker worker = new Worker(storage, sell1, sell2, "集团");
worker.start();
sell1.start();
sell2.start();
//合并线程
try {
sell1.join();
sell2.join();
worker.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
//在除主线程外所以线程执行完毕后再运行
if(storage.getCount1() > storage.getCount2()){
System.out.println("小崔是销售冠军!!!");
}else {
System.out.println("肥总是销售冠军!!!");
}
}
}