多线程并发安全问题详细解释
基础概念
简单理解
-
比如:打开任务管理器可以看到QQ.exe,在windows操作系统中,运行在内存中的
exe文件就是一个进程(受操作系统管理的基本运行单元); -
线程就好像是QQ.exe在运行时同时运行的子任务,比如:好友视频线程、下载文件线程、
数据传输线程、发送表情线程等。 -
简单理解:任务就好像一件事情,线程就好像找了一个人做这件事情。
-
以此类推:多线程就好像是找了多个人做一件事情,或者多个人做多个事情。
串行和并行对比
-
什么是串行:一个时间只找一个人按顺序的做一件事情
- 优势:直观性、简单性
劣势:应用到计算机中就是无法充分利用多处理器的性能。但不一定慢。
就好像一件不是很复杂的事情,找了很多人来做,不一定比一个人做的快,因为有沟通成本。
,但是一件很复杂的事情,跟多个人带来的效率提升相比,这种沟通成本基本可以忽略不及。
- 优势:直观性、简单性
-
什么是并行:一个时间找多个人做多个事情(异步);或者一个大的事情拆成多份找多个人同时来做。
- 优势:对多核CPU的计算机来说就是,充分利用多核处理器的性能,所以程序运行的可能更快。
线程安全相关问题
想象一个场景:账户中有100万,A和B一起取钱,A取了50万,B想要取100万,这个时候无论谁先
取到了💰,如果不加控制、另一个在再取💰就会导致余额变成负数。
- 如果A取完💰再让B来取这种现象就可以避免。
重排序
重排序:重排序是指,编译器和处理器为了优化程序性能而对指令序列进行重新排序的一种手段。
存在数据依赖性的数据,不会进行重排序。因为会改变最终的执行结果。
(关于依赖性包含以下几点)
写后读、写后写、读后写
重排序对多线程的影响:
- 步骤1,2是否重排序会影响i的值
结论:重排序导致线程访问共享变量时,出现与预期结果不一致的情况。
- 解决方案:
使用🔐进行同步,保证线程操作共享变量时,数据不会被其他线程修改。
或者保证数据的原子操作对其他线程的可见性。
或者是使用CAS算法(比较并交换)。
JVM中哪些区域是多线程共享区域
线程安全问题总结:
-
非线程安全问题存在于实例变量中,对于方法内部的私有变量,不存在非线程安全问题。
-
多线程操作同一个对象时是非线程安全的(加锁解决),多个线程操作自己线程下的对象
是线程安全的,无需加锁。 -
此外还有:线程的上下文切换问题、死锁问题等。