多线程实现卖票的例子
来源:互联网 发布:极度干燥 知乎 编辑:程序博客网 时间:2024/05/22 04:51
以卖票的例子来介绍多线程和资源共享。
卖票是包含一系列动作的过程,有各种操作,例如查询票、收钱、数钱、出票等,其中有一个操作是每次卖掉一张,就将总的票数减去1。有10张票,如果一个人卖票,先做查票、收钱、数钱等各种操作,再将总的票数减去1,效率很低。如果多个人卖票,每个人都是做同样的操作,数钱、检查钱,最后将总的票数减1,这样效率高。但是有一个问题,如果出现两个人同时将总的票数减掉了1,例如,A、B两个人同时读取到票的总数是10,A从中减去1,同时B也从中减去1,总数显示是9,其实票只有8张。导致数据错误。
按照正常逻辑,同一时刻只允许一个人来从总票数中减去1,A读取总票数,再减去1的过程中,B必须等待,等A操作完了,B才能进行。其实票就是共享资源,一次只能由一个人访问。这里就要用到同步机制,即锁机制,使用关键词synchronized将读取总的票数,并减去1的操作锁定,使得一次只能由一个人访问。每个售票员就是一个线程,多个售票员进行同一项卖票任务。
synchronized原理是,执行synchronized部分代码的时候必须需要对象锁,而一个对象只有一个锁,只有执行完synchronized里面的代码后释放锁,其他线程才可以获得锁,那么就保证了同一时刻只有一个线程访问synchronized里面的代码。使得资源共享的关键是,只有一个实例,synchronized使用的是同一把锁,用实例的锁或者定义一个实例。这就需要使用实现Runnable接口的方式,实现多线程,这样传入的是一个实例。继承Thread的方式,传入的是多个实例,每个实例都有一个锁,那就无法实现控制。代码如下:
public class SellTicketsThread implements Runnable{private int ticketCount = 50;Object lockObject = new Object();public SellTicketsThread() {}@Overridepublic void run() {while(ticketCount > 0){sellTicket();/** 当前线程休眠,好让其他线程继续执行*/try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}}}public void sellTicket(){synchronized(lockObject){if(ticketCount > 0){System.out.println(Thread.currentThread().getName()+"正在卖第:"+ticketCount+"张票"+",还剩"+(ticketCount-1)+"张票");ticketCount--;} else{System.out.println("票已卖完");return;}}}}
主函数调用:
public class SellTicketsMain {public SellTicketsMain() {}public static void main(String[] args) {SellTicketsThread sellTicketsThread = new SellTicketsThread();Thread firstThread = new Thread(sellTicketsThread, "线程1");Thread secondThread = new Thread(sellTicketsThread, "线程2");Thread thirdThread = new Thread(sellTicketsThread, "线程3");Thread fourthThread = new Thread(sellTicketsThread, "线程4");Thread fifthThread = new Thread(sellTicketsThread, "线程5");firstThread.start();secondThread.start();thirdThread.start();fourthThread.start();fifthThread.start();}}
执行结果:
线程1正在卖第:50张票,还剩49张票
线程2正在卖第:49张票,还剩48张票
线程3正在卖第:48张票,还剩47张票
线程4正在卖第:47张票,还剩46张票
线程5正在卖第:46张票,还剩45张票
线程4正在卖第:45张票,还剩44张票
线程2正在卖第:44张票,还剩43张票
线程1正在卖第:43张票,还剩42张票
线程3正在卖第:42张票,还剩41张票
线程5正在卖第:41张票,还剩40张票
线程5正在卖第:40张票,还剩39张票
线程4正在卖第:39张票,还剩38张票
线程2正在卖第:38张票,还剩37张票
线程1正在卖第:37张票,还剩36张票
线程3正在卖第:36张票,还剩35张票
线程5正在卖第:35张票,还剩34张票
线程3正在卖第:34张票,还剩33张票
线程1正在卖第:33张票,还剩32张票
线程2正在卖第:32张票,还剩31张票
线程4正在卖第:31张票,还剩30张票
线程5正在卖第:30张票,还剩29张票
线程3正在卖第:29张票,还剩28张票
线程1正在卖第:28张票,还剩27张票
线程2正在卖第:27张票,还剩26张票
线程4正在卖第:26张票,还剩25张票
线程2正在卖第:25张票,还剩24张票
线程5正在卖第:24张票,还剩23张票
线程3正在卖第:23张票,还剩22张票
线程1正在卖第:22张票,还剩21张票
线程4正在卖第:21张票,还剩20张票
线程4正在卖第:20张票,还剩19张票
线程2正在卖第:19张票,还剩18张票
线程5正在卖第:18张票,还剩17张票
线程3正在卖第:17张票,还剩16张票
线程1正在卖第:16张票,还剩15张票
线程1正在卖第:15张票,还剩14张票
线程4正在卖第:14张票,还剩13张票
线程2正在卖第:13张票,还剩12张票
线程5正在卖第:12张票,还剩11张票
线程3正在卖第:11张票,还剩10张票
线程2正在卖第:10张票,还剩9张票
线程3正在卖第:9张票,还剩8张票
线程5正在卖第:8张票,还剩7张票
线程1正在卖第:7张票,还剩6张票
线程4正在卖第:6张票,还剩5张票
线程3正在卖第:5张票,还剩4张票
线程5正在卖第:4张票,还剩3张票
线程1正在卖第:3张票,还剩2张票
线程4正在卖第:2张票,还剩1张票
线程2正在卖第:1张票,还剩0张票
- 多线程实现卖票的例子
- 多线程--简单的卖票例子--基础
- Java 多线程卖票例子
- 实现Runnable 多线程卖票
- 多线程runnable实现卖票
- JAVA多线程实现模拟卖票
- 【java】多线程小例子(卖票示例)
- 多线程卖票
- 接上一篇文章实现runnable接口来进行synchronized()后卖票的例子
- 利用多线程模拟卖票的功能
- 多线程的使用实列-卖票系统
- java多线程重复卖票的问题
- java基础--24.多线程的应用--电影院卖票程序的实现
- jdk5的多线程实现例子
- 一个实现多线程的例子
- 简单多线程实现代码(参考卖票代码)
- 简单多线程实现代码(参考卖票代码)
- Java---12---多线程练习:卖票---实现数据共享
- PDF转CAD文件怎么设置输出类型
- rman 0级1级增量备份
- 双路快速排序法
- 用telnet+网址可以连接,但进入telnet后,用open+网址无法连接
- CMAQ搭建教程之netcdf C安装
- 多线程实现卖票的例子
- iOS11: 使用Xcode9后的11条小建议 韩俊强的博客
- opencv 三种算法
- 排序算法之选择排序
- RSA的实现原理
- Linux
- select 的onchange方法失效问题
- 神经网络中梯度下降算法原理
- Android 实现根据录音分贝画波浪线