JAVA-初步认识-第十三章-多线程(线程安全问题的现象)

一. 引言

接着看,把售票的问题给说完,这里涉及到一个小问题。

在我们进行线程任务封装,并进行线程对象创建的时候,我们发现确实通过四个线程能够将一百张票卖完。但是卖票的时候,会不会出现一些小问题呢?分析整个程序给大家展示一下。

现在有四个线程,都到了run方法中来运行。大家都知道,每个线程所属的栈区当中都有自己的run方法,比如它们同时在操作堆内存中的变量,叫做num。

假设这个num已经减到了1,这是个前提。

在num=1的情况下,四个线程Thread-0,Thread-1,Thread-2,Thread-4,都同时进入循环。在Thread-0线程举着num=1,判断完if(num>0)后,cpu切出去执行其他线程的if判断语句了。也就是说保有执行资格,没有执行权。在四个线程判别完之后,cpu回过来执行了Thread-0线程,输出了DOS信息,Thread-0,1,此时num=0了。

同时卧倒的线程还有三个,它们都不用再进行判断了。线程1在执行的时候,输出的是Thread-1,0。当线程输出0的时候,就出事儿了。哪有0号票的,同样的线程3输出的是Thread-3,-1。

这个程序分析完,我们发现存在安全隐患。这就是我们在写多线程程序的时候,必须要注意的一件事。线程的安全问题。

二.

线程的完全问题,多线程是随机的,它就会引发一些安全隐患。这些安全隐患对我们来说是很严重的。

有人说,我们上面的程序在编译运行的时候,没有问题。但那都是理想状态,刚才我们的分析的状态是有可能出现的。

现在将这种情况实现以下,将线程在卧倒的时候稍微停一下,也就是睡一下。有人说,睡不是释放资格吗?不怕,睡的时间特别短就没事。它具备的资格,没有执行权和睡的时间短是一回事。因为都在这段时间内,不运行。

线程怎么睡,自己知道,到Thread类中寻找方法。

下面的sleep方法,是纳秒。由于sleep方法是静态的,所以要类名调用。

点进sleep方法中,发现还有异常的存在。这个异常是中断异常,后面会重点给大家介绍。

我们现在调用了一个抛出异常的方法,那应该怎么办?要么声明throws,要么try-catch处理。如果catch不了,就声明出来。

在if代码块的Thread.sleep(10);语句中,遇到异常了,那么我们就要选择抛出,

但是在这里是抛不出去,你声明不了,是因为这run覆盖的是接口中的方法,接口没有声明过异常,所以覆盖时,你也不能声明异常。

你只能try-catch,确切地说,你只能catch,而不能声明。这就是只能catch,不能声明的情况。

咱这异常目前处理不了,还没开始学习怎么处理这个异常。

这里就没进行处理,但是真实的catch里面一定要有处理,而且是针对性的处理。

这么写,给大家看一下是否有错号票发生么?

这次结果中只出了-1,没有出-2,,只是想说这么个事儿,自己运行的时候,没有看到-1,-2,因为到这种情况,当变成0的时候,其他线程才进来,一判断不满足就不运行了。

现在的结果将之前谈论的安全问题发生了,像这种问题,我们不做下面截图中那句话,代码运行很多次都没有问题,但是只要出现一次就很严重。它不是时时刻刻都出现的,但是不代表它没有安全问题。

因此,我们在写多线程程序的时候,要考虑线程的安全问题。我们要考虑的是造成安全问题的原因是什么?

时间: 2024-10-10 13:51:01

JAVA-初步认识-第十三章-多线程(线程安全问题的现象)的相关文章

“全栈2019”Java多线程第十三章:线程组ThreadGroup详解

难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多线程第十三章:线程组ThreadGroup详解 下一章 "全栈2019"Java多线程第十四章:线程与堆栈详解 学习小组 加入同步学习小组,共同交流与进步. 方式一:关注头条号Gorhaf,私信"Java学习小组". 方式二:关注公众号Gorhaf,回复"Ja

多线程-线程安全问题

1.多线程-线程安全问题演示 多个线程对象运行同一个线程任务代码的时候,一个线程运行到判断语句后被临时阻塞了,下个线程继续判断,直接输出结果,前一个线程再输出的结果,可能会出问题 class Ticket implements Runnable{     private int num = 100;     public void run(){         while(true){             if(num>0){                 try{            

第18章 多线程----线程同步

Java提供了线程同步的机制来防止资源访问的冲突. 1.线程安全 实际开发中,使用多线程程序的情况很多,如银行排号系统.火车站售票系统等.这种多线程的程序通常会发生问题. 以火车站售票系统为例,在代码中判断当前票数是否大于0,如果大于0则执行将该票出售给乘客功能,但当两个线程同时访问这段代码时(假如这时只剩下一张票),第一个线程将票售出,与此同时第二个线程也已经执行完成判断是否有票的操作,并得出结论票数大于0,于是它也执行售出操作,这样就会产生负数.所以在编写多线程程序时,应该考虑到线程安全问题

Java学习笔记—第十三章 数据库编程入门

第十三章 数据库编程入门 了解JDBC Java中对数据库的访问主要是通过JDBC进行的.JDBC是Java数据库连接技术(Java Database Connectivity)的简称,是用于执行SQL语句的API,可以为多种关系数据库提供统一访问.由一组用Java语言编写的类和接口组成.(SQL是Structure Query Language的缩写,意义为结构化查询语言,是一种标准的关系数据库访问语言.) JDBC的工作机制 使用JDBC完成对数据库的访问主要包括以下五个层次:Java应用程

java的多线程:线程安全问题

什么是线程安全? 为什么有线程安全问题? 当多个线程同时共享,同一个全局变量或静态变量,做写的操作时,可能会发生数据冲突问题,也就是线程安全问题.但是做读操作是不会发生数据冲突问题. 抢火车的例子: 一号窗口和二号窗口同时出售火车第九九张,部分火车票会重复出售. 结论发现,多个线程共享同一个全局成员变量时,做写的操作可能会发生数据冲突问题. 二.线程安全解决办法: 问:如何解决多线程之间线程安全问题 答:使用多线程之间同步synchronized或使用锁(lock). 问:为什么使用线程同步或使

再次理解多线程线程安全问题(理解java内存模型后)

1.多线程访问的共享资源存在线程安全问题, 无外乎访问两种共享资源. 1)多线程访问方法区数据.存在线程安全问题,通过加锁 2)多线程访问实例变量:被访问对象是单例时存在线程安全,被访问对象是多例时,是线程安全的. 来说说静态变量.实例变量.局部变量在多线程下的安全问题吧! (一)验证静态变量的线程安全性: (1)从程序执行的图中我们可以看出,执行结果中有错误数据,证明了静态变量是存在资源冲突问题的. (2)程序运行结果图: 5.结论:静态变量也称为类变量,属于类对象所有,位于方法区,为所有对象

关于java Servlet,Struts,springMVC 的线程安全问题

现在主流的java的前端框架有:struts1,struts2,springmvc 还有最根本的servlet; 前些天一个朋友问我这方面的问题,就研究一番: 1.关于struts1: Struts1使用的ActionServlet是单例的,由这一个servlet处理所有.do请求.RequestProcessor也是单例. RequestProcessor的processActionCreate方法: /**   * <p>Return an <code>Action</c

Java学习笔记—第十一章 多线程机制

第十一章 Java多线程机制 了解Java中的进程与线程 1.1 进程:一般程序的结构大致可分为一个入口.一个出口和一个顺序执行的语句序列.程序运行时,系统从程序入口开始,按照语句的执行顺序(包括顺序.分支和循环)完成相应指令,然后从出口退出,程序结束.这样的结构称为进程.可以说,进程就是程序的一次动态执行的过程.一个进程既包括程序的代码,同时也包括系统的资源,如CPU.内存空间等.不同的进程所占用的系统资源都是独立的. 1.2 线程:线程是比进程更小的执行单位.一个进程在执行过程中,为了同时完

第18章 多线程----线程的生命周期

线程具有生命周期,其中包含7中状态,分别为:出生状态.就绪状态.运行状态.等待状态.休眠状态.阻塞状态.死忙状态. 1.线程的休眠 例如:在项目中创建SleepMethodTest类,该类继承了JFrame类,实现在窗体中自动画线段的功能,并且为线段设置颜色,颜色是随机产生的. import java.awt.*; import java.util.*; import javax.swing.*; public class SleepMethodTest extends JFrame { pri