Java 线程安全

要了解Java并发就要从以下几个方面去展开:
1. 什么是进程?
2. 什么是线程?
3. 什么是多线程?
4. 多线程的问题?

1. 进程

进程出现的意义:
脱离了与业务的关联,转化为计算机体系的概念,作为一个实例,可以进一步细化、分化。也就是说:当进程出现,平常意义的一个 “程序” 转化为一个“具有多种状态”、“利用系统资源”、“可与其他同样实例共同竞争CPU” 从而“实现处理业务”的 “任务活动”。

随着操作系统的并发和共享性展现,进程的概念浮出水面。
  • 并发:计算机系统中同时存在多个运行中的程序,操作系统具有同时处理和调度多个程序同时执行的能力。
  • 共享:系统中的资源可供内存中多个并发执行的进程同时使用。

如何理解程序和进程的不同?

program: a plan for the programming of a mechainsm (as a computer)
程序:为了实现某种机制的程序设计(简译)
process: a series of things that are done in order to achieve a particular result
进程:为了实现某种机制而执行的一系列动作

因为操作系统的并发和共享性,使用“程序”来作为系统的调度单位已经不符合实际,而进程所展现的间断性、共享性更符合操作系统工作过程。

更重要的是,进程更符合系统工作过程中动态性、过程性的实体运作过程。
就像工厂中我们一般叫做流水线,而不叫其他与加工、制造更贴切的名称(瞎编的)

当然不是名称上的改变而已,进程已经是和程序不同的两个概念。有着不同的特征。

2. 线程——为优化而生

进程可以理解为一个程序的一次动态执行过程,经过创建、运行、阻塞、销毁等状态变化完成了一次功能的实现。

那为什么还需要线程的出现?

个人理解:拥有资源和被调度二者不可兼得,尤其是拥有庞大资源的单位,进程是拥有资源的基本单位,这意味着进程本身是一个重量级的组件,如果同时作为被CPU调度的基本单位,会对调度过程产生影响,因此从资源单位分化出调度单位很有必要。

引出几个概念:
进程是拥有资源的基本单位,线程不拥有系统资源,但线程可以访问隶属进程的系统资源,同一进程的各个线程共享该进程的所有资源。

线程是调度的基本单位。

3. 多线程——进程实现的功能可以继续划分多个子功能

并发场景。

4. 多线程的问题

铺垫了这么多,终于到了重点位置。

总结:多线程为什么会有问题?
(1)顺序问题:功能决定顺序,执行不保证顺序导致出现问题
i = a+b*c , 代码本身就决定了它具有顺序,先执行乘法,后执行加法,我开启两个线程来实现
t1(a,b)实现加法,t2(a,b)实现乘法,但是因为线程的调度策略(时间片轮换)不保证顺序,无法保证 t2 在 t1之前实现。

(2)原子问题:功能决定原子问题,执行不保证原子问题。 i++,代码本身决定它是一个i = i+1 的原子操作,但是多线程下(线程调度的时机不确定),可能在取到i之后,CPU开始调度其他线程,导致原子问题
(3)java 本身的问题:Java的主内存与工作内存,可以理解为因为加了缓存导致的不一致问题。线程1改变某个值在线程1的工作内存,线程2也对该值处理,但是被线程1修改后的值因为没有同步到主内存导致线程2处理时没拿到出现问题。(可见性问题)

详细来讲:

(1)顺序问题
常见的重排序会导致多线程安全问题。为了优化执行,执行器会采用乱序执行的过程,在单线程的场景下是一种有效的优化手段,但是在多线程下会导致问题。
解决方案:volatile

(2)原子问题
这里又牵扯到读写问题,一个资源如果可以被共享,又可以细分为:
共读、共写。
解决方案:加锁

(3)缓存所带来的数据不一致问题
可见性问题。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值