Java线程安全问题
线程安全问题是一个老生常谈的问题,那么多线程环境下究竟有那些问题呢?这么说吧,问题的形式多种多样的,归根结底的说是共享资源问题,无非可见性与有序性问题。
1. 可见性
可见性是对于内存中的共享资源来说。线程作为单一的控制流,在运行的程序内线程必须拥有一些资源作为开销。例如线程的堆栈和私有的程序计数器,线程之间的堆栈是不共享的,每个线程都有自己的堆栈,当然在Java中对于线程私有的内存区域只有程序执行栈与程序计数器。每个线程的运算操作都在自己的执行栈中进行。正是由于这样的结构设计,所以对于内存我们可以分为共享内存(Java中的堆)和工作内存(线程执行栈)。
对于共享内存而言,线程并不会直接去操作它,线程对于数据的运算也并不是直接发生在共享内存中的。这里有一个值拷贝的过程,线程在执行时会将用到的共享数据从共享内存中拷贝到工作内存中,从工作内存中完成计算之后,再复制到共享内存中。

所以当多线程操作共享内存时,一个线程修改了主内存的内容,那么其他线程是否能察觉到主内存的变化呢?对于可见性有一个经典的ABA问题。其实造成ABA问题的根本原因是因为内存的可见性问题。当一个线程修改了内存值之后,其他线程并不能立刻感知到。
2. 有序性
谈到有序性就要说起操作系统的调度算法了。我们知道线程是操作系统所能调度的最小单元,既然线程归操作系统调度,那么它是如何调度的呢?不同应用场景下的调度算法不太一致,常见的调度算法有时间片轮转算法与多级反馈队列,一般的分时操作系统都会采用时间片轮转算法进行线程的调度。
所谓时间片轮转算法,就是给每个线程一定的执行时间片。当这个线程的时间片用完之后就会调度另一个线程执行。通过这个算法的特点我们便知道,如果使用这样的算法,那么程序执行的单位变成了时间片,而并不是一次程序执行。正是这样就不能保障在时间片使用完毕后,程序能够按照正常的执行逻辑停止运行交出使用权。也就是说程序停止的位置具有不确定性。这样一来顺序的控制流就变得无序了。而无序也无伤大雅,重点是对于共享资源的访问,不能无序,要有序访问共享资源。
同时,有序性的另一个层面是线程同步问题。线程的调度由操作系统负责,多个线程执行的顺序我们无法得知。这样线程执行顺序的的无序有时也会带来问题。
Java线程安全问题的更多相关文章
- (转)java线程安全问题之静态变量、实例变量、局部变量
java多线程编程中,存在很多线程安全问题,至于什么是线程安全呢,给出一个通俗易懂的概念还是蛮难的,如同<java并发编程实践>中所说: 写道 给线程安全下定义比较困难.存在很多种定义,如 ...
- java线程安全问题以及使用synchronized解决线程安全问题的几种方式
一.线程安全问题 1.产生原因 我们使用java多线程的时候,最让我们头疼的莫过于多线程引起的线程安全问题,那么线程安全问题到底是如何产生的呢?究其本质,是因为多条线程操作同一数据的过程中,破坏了数据 ...
- java线程安全问题之静态变量、实例变量、局部变量
java多线程编程中,存在很多线程安全问题,至于什么是线程安全呢,给出一个通俗易懂的概念还是蛮难的,如同<java并发编程实践>中所说: 写道 给线程安全下定义比较困难.存在很多种定义,如 ...
- Java 线程安全问题
线程安全问题产生原因: 1.多个线程操作共享的数据: 2.操作共享数据的线程代码有多条. 当一个线程正在执行操作共享数据的多条代码过程中,其它线程也参与了运算, 就会导致线程安全问题的发生. cl ...
- java线程安全问题原因及解决办法
1.为什么会出现线程安全问题 计算机系统资源分配的单位为进程,同一个进程中允许多个线程并发执行,并且多个线程会共享进程范围内的资源:例如内存地址.当多个线程并发访问同一个内存地址并且内存地址保存的值是 ...
- Java 线程安全问题的本质
原创声明:作者:Arnold.zhao 博客园地址:https://www.cnblogs.com/zh94 目录: 线程安全问题的本质 理解CPU JVM虚拟机类比于操作系统 重排序 汇总 一些解释 ...
- java线程安全问题原理性分析
1.什么是线程安全问题? 从某个线程开始访问到访问结束的整个过程,如果有一个访问对象被其他线程修改,那么对于当前线程而言就发生了线程安全问题:如果在整个访问过程中,无一对象被其他线程修改,就是线程安全 ...
- 关于 SimpleDateFormat 的非线程安全问题及其解决方案
一直以来都是直接用SimpleDateFormat开发的,没想着考虑线程安全的问题,特记录下来(摘抄的): 1.问题: 先来看一段可能引起错误的代码: package test.date; impor ...
- Java多线程--线程安全问题的相关研究
在刚刚学线程的时候我们经常会碰到这么一个问题:模拟火车站售票窗口售票.代码如下: package cn.blogs.com.isole; /* 模拟火车站售票窗口售票,假设有50张余票 */ publ ...
随机推荐
- NLP论文阅读一:Paper阅读方法
参考:https://pan.baidu.com/s/1MfcmXKopna3aLZHkD3iL3w 一.为什么要读论文? 基础技术:读论文中的related works可以帮助了解该领域的一些主要的 ...
- Atlas 分表功能
目录 分表原因 分表方式 Atlas 分表 分表思路 配置 Atlas 创建原表 创建分表 数据测试 分表原因 1.数据过多,访问缓慢 2.创建索引时重新排序,创建缓慢,并且占用大量的磁盘空间 分表方 ...
- 【python接口自动化】- PyMySQL数据连接
什么是 PyMySQL? PyMySQL是在Python3.x版本中用于连接MySQL服务器的一个库,Python2中则使用mysqldb.它是一个遵循 Python数据库APIv2.0规范, ...
- 一些CTF题目--20/9/3
1. 看源码 POST方法.Extract覆盖. 直接url ?参数不行,因为POST参数不在URL上,GET参数才在 Burpsuite抓包,改成 pass=1&thepassword_1 ...
- Gym 101170I Iron and Coal(BFS + 思维)题解
题意:有一个有向图,有些点是煤,有些点是铁,但不会同时有铁和煤.现在我要从1出发,占领可以到达的点.问最少占领几个点能同时拥有一个煤和一个铁(1不用占领). 思路:思路很秀啊.我们从1往外bfs,得到 ...
- Spring应用上下文生命周期
Spring应用上下文生命周期整体分成四个阶段 ConfigurableApplicationContext#refresh,加载或者刷新持久化配置 ConfigurableApplicationCo ...
- chown -R & chmod 777 & chmod +x
chown -R & chmod 777 & chmod +x https://linux.die.net/man/1/chown chown - change file owner ...
- virtual scroll list / dynamic dom list
virtual scroll list / dynamic dom list 虚拟滚动列表 1亿条数据的处理渲染方法 时间分片,不阻塞 DOM web workers 后台进程 Array buffe ...
- 【java】ObjectOutputStream & ObjectInputStream 多次写入发生重复写入相同数据的问题
今日份代码,解决 ObjectOutputStream 多次写入发生重复写入相同数据的问题 核心区别如下: package com.sxd.swapping.objoutputstream; impo ...
- .Net按模板导出Excel
最近在项目中遇到需求 需要按照一定的模板导出数据 还是直接上代码 这里贴一部分模板长什么样吧 然后就是代码 大致就是找到模板 复制一份临时文件 然后修改临时文件然后导出数据 代码如下 string a ...