目录

  • 案例:卖票
  • 出现的问题
  • 解决方法:
    • 方式一:同步代码块
    • 方式二:同步方法
    • 方式三: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();}
}

出现的问题

  1. 问题:卖票过程中,出现了重票、错票 --> 出现了线程的安全问题
  2. 问题出现的原因:当某个线程操作车票的过程中,尚未操作完成时,其他线程参与进来,也操作车票。
  3. 如何解决:当一个线程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();}
}

卖票问题 - 三种解决方法相关推荐

  1. 打开计算机后 无法最小化,最小化窗口后无法在任务栏中显示的三种解决方法...

    [文章导读]最近有用户反映打开的窗口最小化后无法在任务栏中显示,通常情况下点击程序的最小化按钮都会显示在任务栏中,方便我们点击再次打开. 最近有用户反映打开的窗口最小化后无法在任务栏中显示,通常情况下 ...

  2. PHP no input file specified 三种解决方法

    PHP no input file specified 三种解决方法 参考文章: (1)PHP no input file specified 三种解决方法 (2)https://www.cnblog ...

  3. MapperException: 无法获取实体类xxxxx对应的表名! 三种解决方法,总有一款适合你。

    MapperException: 无法获取实体类xxxxx对应的表名! 三种解决方法,总有一款适合你. 参考文章: (1)MapperException: 无法获取实体类xxxxx对应的表名! 三种解 ...

  4. html没有注册类,电脑中ie浏览器提示没有注册类别的三种解决方法

    ie浏览器功能十分强大,能够给我们带来很棒的网页浏览体验.不过,一些朋友反馈自己在使用ie浏览器过程中,突然遇到"没有注册类别"的出错提示,这是怎么回事呢?其实这是文件的丢失等原因 ...

  5. linux电脑滚轮不能用,图文详解电脑鼠标滚轮不动了怎么办_电脑鼠标滚轮不能用的三种解决方法-系统城...

    近期,许多小伙伴发现电脑鼠标滚轮失灵了,无缘无故的就无法使用,浏览网页玩游戏都没办法继续进行,真的很麻烦.针对电脑鼠标滚轮不动了的故障,小编收集整理具体原因和解决方法给大家,希望大家采纳! 原因一:鼠 ...

  6. 计算机键盘输入错乱,win10电脑键盘错乱的三种解决方法

    近期,看到许多小伙伴抱怨说win10电脑更新后键盘错乱了,平时聊天.玩游戏都会用到键盘,键盘错乱严重影响使用体验,有什么办法解决呢?其实可以试试更新驱动,或者杀毒一下,下面一起来看看具体的三种解决方法 ...

  7. outlook邮箱邮件大小限制_Office Outlook 2010、2013附件大小超过了允许的范围限制三种解决方法图解...

    在outlook2010.2013中添加附件超过20M,就会提示:"附件大小超出了允许的范围"! outlook2007的附件默认大小是150M,而outlook2010.2013 ...

  8. outlook邮箱邮件大小限制_Office Outlook 2010、2013附件大小超过了允许的范围限制三种解决方法图解 – 爱分享...

    在outlook2010.2013中添加附件超过20M,就会提示:"附件大小超出了允许的范围"! outlook2007的附件默认大小是150M,而outlook2010.2013 ...

  9. 应用程序错误电脑黑屏_电脑运行程序出现APPCRASH错误的三种解决方法

    好多小伙伴说电脑在运行程序时出现appcrash错误,导致软件无法正常运行,其实电脑是很复杂的程序代码设计的,遇到一些奇怪的问题也不奇怪,系统运行程序出现APPCRASH错误,很多新手用户都不知道怎么 ...

最新文章

  1. Pwnium CTF2014 – MatterOfCombination writeup
  2. cocob optimizer让学习率不再是算法参数
  3. boost::math::quadrature::exp_sinh用法的测试程序
  4. 如何在线把网站html生成xml文件_Sitemap在线生成器,网站地图在线生成工具
  5. 用GDI+转BMP为WMF、EXIF、EMF格式
  6. WWW软件全球使用排名
  7. 强一致性、弱一致性、最终一致性
  8. Linux内核多线程(二)
  9. 阿里二面:我们为什么要做分库分表?
  10. java连接达梦数据库_java连接达梦数据库的简单代码
  11. Java动态生成excel模板、和动态模板数据导出
  12. 自由软件的开源许可介绍(GPL、BSD、LGPL、Apache License 2.0)
  13. Oracle中nlssort 中文 排序 用法
  14. Cesium 绘制不同的形状(Entity)
  15. Papi酱: 左手奶瓶右手尿布× 左手papitube右手娱乐圈√
  16. 프로그래머로 살아남는 법
  17. 命令行实现URL编解码
  18. 使用yagmail模块群发工资条
  19. 参考文献怎么缩进换行
  20. 安卓期末大作业——Android数独游戏

热门文章

  1. WordPress爱导航主题 1.1.3 简约大气网站导航源码网址导航源码
  2. 效率最高的Excel数据导入---(c#调用SSIS Package将数据库数据导入到Excel文件中【附源代码下载】) 转...
  3. markdown组合数学公式
  4. 什么,你还在一条一条的insert?
  5. 同程旅游——Java开发面经
  6. 揭发一名以淘宝订单异常退款的骗子
  7. 中标linux+银河麒麟=中标麒麟
  8. BTChina被关的原因(文)btchina关闭(转)
  9. 抖音seo账号矩阵霸屏系统源码/账号矩阵系统搭建部署
  10. Oracle获得数据库中table和table中column