卖票问题 - 三种解决方法
目录
- 案例:卖票
- 出现的问题
- 解决方法:
- 方式一:同步代码块
- 方式二:同步方法
- 方式三:Lock锁
案例:卖票
/**例子:创建三个窗口卖票,总票数为100张.使用实现Runnable接口的方式* @author dsstart* @create 2020-11-30 13:28*/
public class SellTicket implements Runnable {private int ticket = 100;@Overridepublic void run() {while (true){//问题放大try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}if (ticket > 0){/*currentThread():静态方法,返回执行当前代码的线程getName():获取当前线程的名字*/System.out.println(Thread.currentThread().getName()+ " 卖票,票号为: "+ ticket);ticket--;}else{System.out.println("卖完了!");break;}}}public static void main(String[] args) {SellTicket sellTicket = new SellTicket();//创建三个卖票窗口Thread window1 = new Thread(sellTicket);Thread window2 = new Thread(sellTicket);Thread window3 = new Thread(sellTicket);//给三个窗口命名//setName():设置当前线程的名字window1.setName("窗口一");window2.setName("窗口二");window3.setName("窗口三");//启动window1.start();window2.start();window3.start();}
}
出现的问题
- 问题:卖票过程中,出现了重票、错票 --> 出现了线程的安全问题
- 问题出现的原因:当某个线程操作车票的过程中,尚未操作完成时,其他线程参与进来,也操作车票。
- 如何解决:当一个线程a在操作ticket的时候,其他线程不能参与进来。直到线程a操作完ticket时,其他线程才可以开始操作ticket。这种情况即使线程a出现了阻塞,也不能被改变。
解决方法:
方式一:同步代码块
/*** synchronized(同步监视器){** //需要被同步的代码** }* 说明:1.操作共享数据的代码,即为需要被同步的代码。 -->不能包含代码多了,也不能包含代码少了。* 2.共享数据:多个线程共同操作的变量。比如:ticket就是共享数据。* 3.同步监视器,俗称:锁。任何一个类的对象,都可以充当锁。** 要求:多个线程必须要共用同一把锁。** 补充:在实现Runnable接口创建多线程的方式中,我们可以考虑使用this充当同步监视器。在继承Thread类创建多线程的方式中,慎用this充当同步监视器,考虑使用当前类充当同步监视器。* @author dsstart* @create 2020-11-30 13:47*/
public class Method01 implements Runnable {private int ticket = 100;Object obj = new Object();//注意:多个线程必须要使用同一把锁!@Overridepublic void run() {synchronized (obj){try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}while (ticket > 0){System.out.println( Thread.currentThread().getName() + "出票,票号为:" + ticket);ticket--;}}}public static void main(String[] args) {Method01 sellTicket = new Method01();Thread w1 = new Thread(sellTicket);Thread w2 = new Thread(sellTicket);Thread w3 = new Thread(sellTicket);w1.start();w2.start();w3.start();}
}
方式二:同步方法
/*** 如果操作共享数据的代码完整的声明在一个方法中,我们不妨将此方法声明同步的。* 关于同步方法的总结:* 1. 同步方法仍然涉及到同步监视器,只是不需要我们显式的声明。* 2. 非静态的同步方法,同步监视器是:this* 静态的同步方法,同步监视器是:当前类本身* @author dsstart* @create 2020-11-30 13:47*/
public class Method02 implements Runnable {private int ticket = 100;@Overridepublic synchronized void run() {try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}while (ticket > 0){System.out.println( Thread.currentThread().getName() + "出票,票号为:" + ticket);ticket--;}}public static void main(String[] args) {Method02 sellTicket = new Method02();Thread w1 = new Thread(sellTicket);Thread w2 = new Thread(sellTicket);Thread w3 = new Thread(sellTicket);w1.start();w2.start();w3.start();}
}
方式三:Lock锁
/*** @author dsstart* @create 2020-11-30 17:51*/
public class Method03 implements Runnable {private int ticket = 100;// 1 实例化锁private ReentrantLock lock = new ReentrantLock();@Overridepublic void run() {try {// 2 上锁lock.lock();try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}while (ticket > 0){System.out.println( Thread.currentThread().getName() + "出票,票号为:" + ticket);ticket--;}} finally {// 3 解锁lock.unlock();}}public static void main(String[] args) {Method03 sellTicket = new Method03();Thread w1 = new Thread(sellTicket);Thread w2 = new Thread(sellTicket);Thread w3 = new Thread(sellTicket);w1.start();w2.start();w3.start();}
}
卖票问题 - 三种解决方法相关推荐
- 打开计算机后 无法最小化,最小化窗口后无法在任务栏中显示的三种解决方法...
[文章导读]最近有用户反映打开的窗口最小化后无法在任务栏中显示,通常情况下点击程序的最小化按钮都会显示在任务栏中,方便我们点击再次打开. 最近有用户反映打开的窗口最小化后无法在任务栏中显示,通常情况下 ...
- PHP no input file specified 三种解决方法
PHP no input file specified 三种解决方法 参考文章: (1)PHP no input file specified 三种解决方法 (2)https://www.cnblog ...
- MapperException: 无法获取实体类xxxxx对应的表名! 三种解决方法,总有一款适合你。
MapperException: 无法获取实体类xxxxx对应的表名! 三种解决方法,总有一款适合你. 参考文章: (1)MapperException: 无法获取实体类xxxxx对应的表名! 三种解 ...
- html没有注册类,电脑中ie浏览器提示没有注册类别的三种解决方法
ie浏览器功能十分强大,能够给我们带来很棒的网页浏览体验.不过,一些朋友反馈自己在使用ie浏览器过程中,突然遇到"没有注册类别"的出错提示,这是怎么回事呢?其实这是文件的丢失等原因 ...
- linux电脑滚轮不能用,图文详解电脑鼠标滚轮不动了怎么办_电脑鼠标滚轮不能用的三种解决方法-系统城...
近期,许多小伙伴发现电脑鼠标滚轮失灵了,无缘无故的就无法使用,浏览网页玩游戏都没办法继续进行,真的很麻烦.针对电脑鼠标滚轮不动了的故障,小编收集整理具体原因和解决方法给大家,希望大家采纳! 原因一:鼠 ...
- 计算机键盘输入错乱,win10电脑键盘错乱的三种解决方法
近期,看到许多小伙伴抱怨说win10电脑更新后键盘错乱了,平时聊天.玩游戏都会用到键盘,键盘错乱严重影响使用体验,有什么办法解决呢?其实可以试试更新驱动,或者杀毒一下,下面一起来看看具体的三种解决方法 ...
- outlook邮箱邮件大小限制_Office Outlook 2010、2013附件大小超过了允许的范围限制三种解决方法图解...
在outlook2010.2013中添加附件超过20M,就会提示:"附件大小超出了允许的范围"! outlook2007的附件默认大小是150M,而outlook2010.2013 ...
- outlook邮箱邮件大小限制_Office Outlook 2010、2013附件大小超过了允许的范围限制三种解决方法图解 – 爱分享...
在outlook2010.2013中添加附件超过20M,就会提示:"附件大小超出了允许的范围"! outlook2007的附件默认大小是150M,而outlook2010.2013 ...
- 应用程序错误电脑黑屏_电脑运行程序出现APPCRASH错误的三种解决方法
好多小伙伴说电脑在运行程序时出现appcrash错误,导致软件无法正常运行,其实电脑是很复杂的程序代码设计的,遇到一些奇怪的问题也不奇怪,系统运行程序出现APPCRASH错误,很多新手用户都不知道怎么 ...
最新文章
- Pwnium CTF2014 – MatterOfCombination writeup
- cocob optimizer让学习率不再是算法参数
- boost::math::quadrature::exp_sinh用法的测试程序
- 如何在线把网站html生成xml文件_Sitemap在线生成器,网站地图在线生成工具
- 用GDI+转BMP为WMF、EXIF、EMF格式
- WWW软件全球使用排名
- 强一致性、弱一致性、最终一致性
- Linux内核多线程(二)
- 阿里二面:我们为什么要做分库分表?
- java连接达梦数据库_java连接达梦数据库的简单代码
- Java动态生成excel模板、和动态模板数据导出
- 自由软件的开源许可介绍(GPL、BSD、LGPL、Apache License 2.0)
- Oracle中nlssort 中文 排序 用法
- Cesium 绘制不同的形状(Entity)
- Papi酱: 左手奶瓶右手尿布× 左手papitube右手娱乐圈√
- 프로그래머로 살아남는 법
- 命令行实现URL编解码
- 使用yagmail模块群发工资条
- 参考文献怎么缩进换行
- 安卓期末大作业——Android数独游戏
热门文章
- WordPress爱导航主题 1.1.3 简约大气网站导航源码网址导航源码
- 效率最高的Excel数据导入---(c#调用SSIS Package将数据库数据导入到Excel文件中【附源代码下载】) 转...
- markdown组合数学公式
- 什么,你还在一条一条的insert?
- 同程旅游——Java开发面经
- 揭发一名以淘宝订单异常退款的骗子
- 中标linux+银河麒麟=中标麒麟
- BTChina被关的原因(文)btchina关闭(转)
- 抖音seo账号矩阵霸屏系统源码/账号矩阵系统搭建部署
- Oracle获得数据库中table和table中column