JavaSE——多线程部分案例之“车站卖票”、“生产者消费者模型”、“仓储模型”

本文详细介绍了多线程环境下的同步问题,通过车站售票、生产者消费者模型以及仓储模型三个案例,展示了如何在Java中使用锁机制解决线程安全问题。在车站卖票案例中,通过ReentrantLock避免了票的重复销售和负数问题。在生产者消费者模型中,展示了单个和多个生产者、消费者的情况,使用wait和notify方法协调生产与消费。仓储模型则演示了如何通过仓库类控制生产者与消费者的交互。这些案例为理解和应用多线程同步提供了实用示例。

文章目录



前言

我要光明正大地学习,然后惊艳所有人~~~

本次任务的内容是记录的我的三个案例,这三个案例很重要,其基础模型思想涉及到后面的项目开发中的许多设计思想,一定一定要弄懂它


提示:以下是本篇文章正文内容,下面案例可供参考

一、车站卖票的案例:

适用场景:多线程中不同但具有相同功能的线程来操纵共有的数据, 有票1000张。有三个售票窗口,并通过这三个售票窗口进行销售,销售完毕后就显示票已经卖完提示、

创建线程任务类(卖票的任务)


import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class Task implements Runnable{
   
   

    private int ticket = 1000;//由于三个窗口都需要卖票,所以设为全局变量

    private Lock lock = new ReentrantLock();

    @Override
    public void run() {
   
   

        while(ticket > 0){
   
   
            lock.lock();
            if(ticket > 0){
   
   
                System.out.println(Thread.currentThread().getName() + "正在销售第" + ticket + "张票");
                ticket--;
            }
            if(ticket <= 0){
   
   
                System.out.println(Thread.currentThread().getName() + "票已售完");
            }
            lock.unlock();
        }
    }
}

创建启动测试类


public class Test {
   
   

    public static void main(String[] args) {
   
   
        /**
         * 2.铁道部发布了一个售票任务,要求销售1000张票,要求有3个窗口来进行销售,
         * 请编写多线程程序来模拟这个效果
         窗口001正在销售第1000张票
         窗口001正在销售第999张票
         窗口002正在销售第998张票
         。。。
         窗口002正在销售第1张票

         问题1:三个窗口都卖了1000张票,一共卖了3000张
         出现原因:创建了三个售票任务
         解决方案:创建一个售票任务

         问题2:有些票卖了重票
         出现原因:票的输出语句输出后,还没有来得及做票的减减,就被其他线程抢到CPU资源了
         解决方案:票的输出语句 和 票的减减必须同时执行完毕后,才能被其他线程抢到CPU资源了 - 加锁

         问题3:出现负数
         出现原因: 票到了零界点(ticket=1),三个线程都进入循环中
         解决方案:锁中再判断一次

         */
        Task task = new Task();
        Thread t1 = new Thread(task, "窗口001");
        Thread t2 = new Thread(task, "窗口002");
        Thread t3 = new Thread(task, "窗口003");

        t1.start();
        t2.start();
        t3.start();
    }
}

二、“生产者”与“消费者”案例

适用场景:当不同功能的线程控制着同一个资源的时候使用,本次案例通过卖手机的方式来展示

案例一、一个“生产者”与“消费者”的情况下

创建一个手机实体类-----phone


public class Phone {
   
   
    private String brand;
    private  double price;
    public boolean isStore;

    public Phone() {
   
   
    }

    public Phone(String brand, double price) {
   
   
        this.brand = brand;
        this.price = price;
    }

    public String getBrand() {
   
   
        return brand;
    }

    public void setBrand(String brand) {
   
   
        this.brand = brand;
    }

    public double getPrice() {
   
   
        return price;
    }

    public void setPrice(double price) {
   
   
        this.price = price;
    }
    public boolean isStore(){
   
   
        return isStore;
    }
    public void setStore(boolean isStore){
   
   
        this.isStore=isStore;
    }

    @Override
    public String toString() {
   
   
        return "Phone{" +
                "brand='" + brand + '\'' +
                ", price=" + price +
                '}';
    }
}

创建生产者线程


public class Producer extends Thread{
   
   
    private Phone phone;
    public Producer(Phone phone){
   
   
        this.phone=phone;
    }

    @Override
    public void run() {
   
   

        boolean flag=true;
        while (true){
   
   
            synchronized (p
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

sugar-free->小粽子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值