多线程售票python
很多同学在进行编程学习时缺乏系统学习的资料。本页面基于多线程售票python内容,从基础理论到综合实战,通过实用的知识类文章,标准的编程教程,丰富的视频课程,为您在多线程售票python相关知识领域提供全面立体的资料补充。同时还包含 damain、dart、dataset 的知识内容,欢迎查阅!
多线程售票python相关知识
-
多线程售票多线程售票 多线程操作资源类 创建启动线程的写法public Thread(Runnable target, String name).start() 线程的6种状态,线程调用start方法后不会立即执行,而是要等待空闲CPU的调度 使用ReentrantLock保证资源类的安全 package com.zbiti.juc; import lombok.extern.slf4j.Slf4j; import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; //多线程操作资源类 3个售票员 操作 50张票 public
-
python多线程同步售票系统解决思路解决问题场景:假如剩余1000张电影票需要售卖,同时有10家电影App来售卖这1000张电影票。主要的逻辑实现过程是什么,要求使用python技术栈进行解题? 1、分析过程 分析:主要信息点是10家App平台同时售卖1000张电影票。此时,可以使用10个python线程来作为10家App平台,同时售卖必须保证电影票数量的同步,比如A平台卖出了一张票那总共剩余的票数是999,B平台若要再卖出一张票则应该是999-1=998张票。 技术栈分析:python多线程提供了threading模块,并且threading模块提供了同步锁Lock来控制
-
多线程模拟售票需求:某电影院出售某些电影的票(复联3,红高粱....),有三个窗口同时进行售票(100张票),请您设计一个程序,模拟电影院售票两种方式:继承接口(1)synchronized实现public class SellTicketDemo {public static void main(String[] args) {//创建资源类对象(共享资源类/目标对象) SellTicket st = new SellTicket() ; //创建线程类对象 Thread t1 = new Thread(st, "窗口1") ; Thread 
-
Python标准库08 多线程与同步Python主要通过标准库中的threading包来实现多线程。在当今网络时代,每个服务器都会接收到大量的请求。服务器可以利用多线程的方式来处理这些请求,以提高对网络端口的读写效率。Python是一种网络服务器的后台工作语言 (比如豆瓣网),所以多线程也就很自然被Python语言支持。(关于多线程的原理和C实现方法,请参考我之前写的Linux多线程与同步,要了解race condition, mutex和condition variable的概念) 多线程售票以及同步我们使用Python来实现Linux多线程与同步文中的售票程序。我们使用mutex (也就是Python中的Lock类对象) 来实现线程的同步:# A program to simulate selling tickets in multi-thread way# Written by Vameiimport&nbs
多线程售票python相关课程
多线程售票python相关教程
- 2. 售票机制模型 售票机制模型是源于现实生活中的售票场景,从开始的单窗口售票到多窗口售票,从开始的人工统计票数到后续的系统智能在线售票。多并发编程能够实现这一售票场景,多窗口售票情况下保证线程的安全性和票数的正确性。如上图所示,有两个售票窗口进行售票,有一个窗口处理退票,这既是现实生活中一个简单的售票机制。
- 3. 售票机制实现 场景设计:创建一个工厂类 TicketCenter,该类包含两个方法,saleRollback 退票方法和 sale 售票方法;定义一个车票总数等于 10 ,为了方便观察结果,设置为 10。学习者也可自行选择数量;对于 saleRollback 方法,当发生退票时,通知售票窗口继续售卖车票;对 saleRollback 进行特别设置,每隔 5000 毫秒退回一张车票;对于 sale 方法,只要有车票就进行售卖。为了更便于观察结果,每卖出一张车票,sleep 2000 毫秒;创建一个测试类,main 函数中创建 2 个售票窗口和 1 个退票窗口,运行程序进行结果观察。修改 saleRollback 退票时间,每隔 25 秒退回一张车票;再次运行程序并观察结果。实现要求:本实验要求使用 ReentrantLock 与 Condition 接口实现同步机制。实例:public class DemoTest { public static void main(String[] args) { TicketCenter ticketCenter = new TicketCenter(); new Thread(new saleRollback(ticketCenter),"退票窗口"). start(); new Thread(new Consumer(ticketCenter),"1号售票窗口"). start(); new Thread(new Consumer(ticketCenter),"2号售票窗口"). start(); }}class TicketCenter { private int capacity = 10; // 根据需求:定义10涨车票 private Lock lock = new ReentrantLock(false); private Condition saleLock = lock.newCondition(); // 根据需求:saleRollback 方法创建,为退票使用 public void saleRollback() { try { lock.lock(); capacity++; System.out.println("线程("+Thread.currentThread().getName() + ")发生退票。" + "当前剩余票数"+capacity+"个"); saleLock.signalAll(); //发生退票,通知售票窗口进行售票 } finally { lock.unlock(); } } // 根据需求:sale 方法创建 public void sale() { try { lock.lock(); while (capacity==0) { //没有票的情况下,停止售票 try { System.out.println("警告:线程("+Thread.currentThread().getName() + ")准备售票,但当前没有剩余车票"); saleLock.await(); //剩余票数为 0 ,无法售卖,进入 wait } catch (InterruptedException e) { e.printStackTrace(); } } capacity-- ; //如果有票,则售卖 -1 System.out.println("线程("+Thread.currentThread().getName() + ")售出一张票。" + "当前剩余票数"+capacity+"个"); } finally { lock.unlock(); } }}class saleRollback implements Runnable { private TicketCenter TicketCenter; //关联工厂类,调用 saleRollback 方法 public saleRollback(TicketCenter TicketCenter) { this.TicketCenter = TicketCenter; } public void run() { while (true) { try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } TicketCenter.saleRollback(); //根据需求 ,调用 TicketCenter 的 saleRollback 方法 } }}class Consumer implements Runnable { private TicketCenter TicketCenter; public Consumer(TicketCenter TicketCenter) { this.TicketCenter = TicketCenter; } public void run() { while (true) { TicketCenter.sale(); //调用sale 方法 try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } } }}结果验证:线程(1号售票窗口)售出一张票。当前剩余票数9个线程(2号售票窗口)售出一张票。当前剩余票数8个线程(2号售票窗口)售出一张票。当前剩余票数7个线程(1号售票窗口)售出一张票。当前剩余票数6个线程(1号售票窗口)售出一张票。当前剩余票数5个线程(2号售票窗口)售出一张票。当前剩余票数4个线程(退票窗口)发生退票。当前剩余票数5个线程(1号售票窗口)售出一张票。当前剩余票数4个线程(2号售票窗口)售出一张票。当前剩余票数3个线程(2号售票窗口)售出一张票。当前剩余票数2个线程(1号售票窗口)售出一张票。当前剩余票数1个线程(退票窗口)发生退票。当前剩余票数2个线程(1号售票窗口)售出一张票。当前剩余票数1个线程(2号售票窗口)售出一张票。当前剩余票数0个警告:线程(1号售票窗口)准备售票,但当前没有剩余车票警告:线程(2号售票窗口)准备售票,但当前没有剩余车票线程(退票窗口)发生退票。当前剩余票数1个线程(1号售票窗口)售出一张票。当前剩余票数0个警告:线程(2号售票窗口)准备售票,但当前没有剩余车票警告:线程(1号售票窗口)准备售票,但当前没有剩余车票结果分析:从结果来看,我们正确的完成了售票和退票的机制,并且使用了 ReentrantLock 与 Condition 接口。代码片段分析 1:看售票方法代码。public void sale() { try { lock.lock(); while (capacity==0) { //没有票的情况下,停止售票 try { System.out.println("警告:线程("+Thread.currentThread().getName() + ")准备售票,但当前没有剩余车票"); saleLock.await(); //剩余票数为 0 ,无法售卖,进入 wait } catch (InterruptedException e) { e.printStackTrace(); } } capacity-- ; //如果有票,则售卖 -1 System.out.println("线程("+Thread.currentThread().getName() + ")售出一张票。" + "当前剩余票数"+capacity+"个"); } finally { lock.unlock(); } }主要来看方法中仅仅使用了 await 方法,因为退票是场景触发的,售票窗口无需唤醒退票窗口,因为真实的场景下,可能没有退票的发生,所以无需唤醒。这与生产者与消费者模式存在着比较明显的区别。代码片段分析 2:看退票方法代码。public void saleRollback() { try { lock.lock(); capacity++; System.out.println("线程("+Thread.currentThread().getName() + ")发生退票。" + "当前剩余票数"+capacity+"个"); saleLock.signalAll(); //发生退票,通知售票窗口进行售票 } finally { lock.unlock(); } }退票方法只有 signalAll 方法,通知售票窗口进行售票,无需调用 await 方法,因为只要有退票的发生,就能够继续售票,没有库存上限的定义,这也是与生产者与消费者模式的一个主要区别。总结:售票机制与生产者 - 消费者模式存在着细微的区别,需要学习者通过代码的实现慢慢体会。由于售票方法只需要进入 await 状态,退票方法需要唤醒售票的 await 状态,因此只需要创建一个售票窗口的 Condition 对象。
- 1. 前言 本节内容主要是使用 Java 的锁机制对多线程售票案例进行实现。售票案例多数情况下主要关注多线程如何安全的减少库存,也就是剩余的票数,当票数为 0 时,停止减少库存。本节内容除了关注车票库存的减少,还会涉及到退票窗口,能够更加贴切的模拟真实的场景。本节内容需要学习者关注如下两个重点:掌握多线程的售票机制模型,在后续的工作中如果涉及到类似的场景,能够第一时间了解场景的整体结构;使用 Condition 和 Lock 实现售票机制,巩固我们本章节内容所学习的新的锁机制。
- 6. 线程安全问题 谈到线程安全问题,我们先说说什么是共享资源。共享资源:所谓共享资源,就是说该资源被多个线程所持有或者说多个线程都可以去访问该资源。线程安全问题是指当多个线程同时读写一个共享资源并且没有任何同步措施时,导致出现脏数据或者其他不可预见的结果和问题。对于线程安全问题,在进行实际的开发操作过程中,我们要分析一下几点内容,确保多线程环境下的线程安全问题。确定是否是多线程环境:多线程环境下操作共享变量需要考虑线程的安全性;确定是否有增删改操作:多线程环境下,如果对共享数据有增加,删除或者修改的操作,需要谨慎。为了保证线程的同步性,必须对该共享数据进行加锁操作,保证多线程环境下,所有的线程能够获取到正确的数据。如生产者与消费者模型,售票模型;多线程下的读操作:如果是只读操作,对共享数据不需要进行锁操作,因为数据本身未发生增删改操作,不会影响获取数据的准确性。
- 多线程售票案例
- 5. 场景案例 import java.util.concurrent.atomic.AtomicInteger;public class AtomicIntegerTest { // 首先创建一个 AtomicInteger 对象 // 代表《神龙晶晶兽》电影上午场次当前可售的总票数 10 张 private static AtomicInteger currentTicketCount = new AtomicInteger(10); // 主程序 public static void main(String[] args) { // 定义3个售票窗口 for(int i=1; i<=3; i++) { TicketOffice ticketOffice = new TicketOffice(currentTicketCount, i); // 每个售票窗口开始售票 new Thread(ticketOffice).start(); } }}在上面的代码中,先创建了一个 AtomicInteger 对象,然后创建了 3 个售票窗口模拟售票动作 ,接下来每个售票窗口如何动作呢,看下面的代码。import java.util.Random;import java.util.concurrent.atomic.AtomicInteger;/** * 模拟售票窗口 */public class TicketOffice implements Runnable { // 当前可售的总票数 private AtomicInteger currentTicketCount; // 窗口名称(编号) private String ticketOfficeNo; // 售票窗口构造函数 public TicketOffice(AtomicInteger currentTicketCount, int ticketOfficeNo) { this.currentTicketCount = currentTicketCount; this.ticketOfficeNo = "第" + ticketOfficeNo + "售票窗口"; } // 模拟售票逻辑 public void run() { // 模拟不间断的售票工作(生活中有工作时间段控制) while (true) { // 获取当前可售的总票数,如果没有余票就关闭当前售票窗口结束售票,否则继续售票 if (currentTicketCount.get() < 1) { System.out.println("票已售完," + ticketOfficeNo + "结束售票"); return; } // 模拟售票用时 try { Thread.sleep(new Random().nextInt(1000)); } catch (Exception e) {} // 当总票数减1后不为负数时,出票成功 int ticketIndex = currentTicketCount.decrementAndGet(); if (ticketIndex >= 0) { System.out.println(ticketOfficeNo + "已出票,还剩" + ticketIndex + "张票"); } } }}在 TicketOffice 类中,首先通过 get () 获取了当前可售的总票数,在有余票的情况下继续售票。然后随机休眠代替售票过程,最后使用 decrementAndGet () 尝试出票。我们观察一下运行结果。第3售票窗口已出票,还剩9张票第1售票窗口已出票,还剩8张票第2售票窗口已出票,还剩7张票第1售票窗口已出票,还剩6张票第3售票窗口已出票,还剩5张票第3售票窗口已出票,还剩4张票第2售票窗口已出票,还剩3张票第1售票窗口已出票,还剩2张票第3售票窗口已出票,还剩1张票第2售票窗口已出票,还剩0张票票已售完,第2售票窗口结束售票票已售完,第1售票窗口结束售票票已售完,第3售票窗口结束售票在这个案例中,因为存在多个售票窗口同时对一场电影进行售票,如果不对可售票数做并发售票控制,很可能会出现多卖出票的尴尬。例子中没有直接使用 synchronized 关键字做同步控制,而是使用 JDK 封装好的 AtomicInteger 原子工具类实现了并发控制整型变量的操作,是不是很方便呢。至此,大家对 AtomicInteger 已经有了初步的理解,接下来我们继续丰富对 AtomicInteger 工具类的认识。
多线程售票python相关搜索
-
daima
damain
dart
dataset
datasource
datediff
datediff函数
datepicker
datetime
db4o
dbi
dcloud
deallocate
debian安装
debugger
debugging
declaration
declarations
declare
decode函数