自我学习——什么是线程安全问题?


在了解线程安全问题之前,要去了解它的基础知识。

首先!!!

什么是进程?

进程就是一个软件在运行中的状态,从开始运行到运行结束的过程,这就是进程

我们看到的这些单独运行的程序(或者应用)就是一个独立的进程,进程之间是相互独立存在的,不同的进程,数据自然不能相互使用。


在任务管理器里,有个专门的板块显示当前计算机运行的所有进程。一般说的杀死进程就是指强制关闭进程。

什么是线程?

世间万物都可以同时完成很多工作。例如,人体可以同时进行呼吸、血液循环、思考问题等活动。用户既可以使用计算机听歌,也可以编写文档和发送邮件,而这些活动的完成可以同时进行。这种同时执行多个操作的“思想”在 Java 中被称为并发,而将并发完成的每一件事称为线程。换句说就是:进程想要执行任务(功能)需要依赖线程,换句话说就是进程中的最小执行单位就是线程,并且一个进程中至少有一个线程。进程=多个线程的集合体(或者是一个线程)
再说一句:一个线程由一个方法启动,一个线程里面可以有多个方法,主方法是一个线程,并不是每个方法都是一个线程。

什么是多线程?

提到多线程这里要说两个概念,就是串行和并行,搞清楚这个我们才能更好的理解多线程。

所谓串行其实是相对于单条线程来执行多个任务来说的,我们就拿下载文件来举个例子,我们下载多个文件,在串行中它是按照一定的顺序去进行下载的,也就是说必须等下载完A之后,才能开始下载B,它们在时间上是不可能发生重叠的。

在这里插入图片描述
并行:下载多个文件,开启多条线程,多个文件同时进行下载,这里是严格意义上的在同一时刻发生的,并行在时间上是重叠的。
在这里插入图片描述

总结一下:一个进程运行时产生了多个线程。

什么是线程安全?

在java中线程安全就是线程同步的意思,就是当一个程序对一个线程安全的方法或者语句进行访问的时候,其他的不能再对他进行操作了,必须等到这次访问结束以后才能对这个线程安全的方法进行访问

如果你的代码所在的进程中有多个线程在同时运行,而这些线程可能会同时运行这段代码。如果每次运行结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的是一样的,就是线程安全的。
或者说:一个类或者程序所提供的接口对于线程来说是原子操作或者多个线程之间的切换不会导致该接口的执行结果存在二义性,也就是说我们不用考虑同步的问题。
线程安全问题都是由全局变量及静态变量引起的。
若每个线程中对全局变量、静态变量只有读操作,而无写操作,一般来说,这个全局变量是线程安全的;若有多个线程同时执行写操作,一般都需要考虑线程同步,否则就可能影响线程安全。存在竞争的线程不安全,不存在竞争的线程就是安全的。

什么是线程安全问题?

多线程操作共享资源时,导致共享资源出现错乱。线程安全问题都是由全局变量及静态变量引起的。若每个线程中对全局变量、静态变量只有读操作,而无写操作,一般来说,这个全局变量是线程安全的;若有多个线程同时执行写操作,一般都需要考虑线程同步,否则的话就可能影响线程安全。

那么

线程安全问题产生的根本原因是?

  1. 先是多线程环境,即同时存在有多个操作者,单线程环境不存在线程安全问题。在单线程环境下,任何操作包括修改操作都是操作者自己发出的,操作者发出操作时不仅有明确的目的,而且意识到操作的影响。
  2. 多个操作者(线程)必须操作同一个对象,只有多个操作者同时操作一个对象,行为的影响才能立即传递到其他操作者。
  3. 多个操作者(线程)对同一对象的操作必须包含修改操作,共同读取不存在线程安全问题,因为对象不被修改,未发生变化,不能产生影响。

综上可知,线程安全问题产生的根本原因是共享数据存在被并发修改的可能,即一个线程读取时,允许另一个线程修改。

线程安全问题解决思路?

根据线程安全问题产生的条件,解决线程安全问题的思路是消除产生线程安全问题的环境:

  1. 消除共享数据:成员变量与静态变量多线程共享,将这些全局变量转化为局部变量,局部变量存放在栈,线程间不共享,就不存在线程安全问题产生的环境了。消除共享数据的不足:如果需要一个对象采集各个线程的信息,或者在线程间传递信息,消除了共享对象就无法实现此目的。
  2. 使用线程同步机制:给读写操作同时加锁,使得同时只有一个线程可以访问共享数据。如果单单给写操作加锁,同时只有一个线程可以执行写操作,而读操作不受限制,允许多线程并发读取,这时就可能出现不可重复读的情况,如一个持续时间比较长的读线程,相隔较长时间读取数组同一索引位置的数据,正好在这两次读取的时间内,一个线程修改了该索引处的数据,造成该线程从同一索引处前后读取的数据不一致。是同时给读写加锁,还是只给写加锁,根据具体需求而定。同步机制的缺点是降低了程序的吞吐量。
  3. 建立副本:使用ThreadLocal为每一个线程建立一个变量的副本,各个线程间独立操作,互不影响。该方式本质上是消除共享数据思想的一种实现。

持续学习,日后更新~~~

参考资料:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值