多线程与高并发-part2

线程安全问题

  1. 主要是指多个线程对同一个对象的实例变量进行操作的时候,会出现值被更改,值不同步。
  2. 线程安全体现:
    1. 原子性
    2. 可见性
    3. 有序性

原子性

  • 要么全部成功,要么全部失败
  • Java两种方式实现原子性:
    1. 使用锁
    2. CAS指令
  • 锁具有排他性,保证共享变量在某一个线程只能被同一个线程访问
  • CAS指令直接在硬件层次上实现的。

可见性

  • 多线程的时候,一个线程对某个共享变量进行更新之后,要通知其他线程知道该变量值已经发生改变。
  • 因为可见性的问题可能导致其他线程读取到旧数据,产生脏读。

有序性

  • 在什么情况下一个处理器上运行的一个线程所执行的内存访问操作,在另外一个处理器运行的其他线程看来是乱序的
  • 乱序是指内存访问操作的顺序看起来发生了变化

重排序

  • 这种一个处理器上执行的多个操作,在其他处理器来看它的顺序与目标代码指定的顺序可能不一样,这种现象称为重排序
  • 编译器可能为改变两个操作的先后顺序,处理器也可能不会按照目标代码的顺序执行

指令重排序

  • 在源码顺序与程序顺序不一致,或者程序顺序与执行顺序不一致情况下,就发生了指令重排。
  • 指令重排不会对单线程的程序结果正确性产生影响,但是可能会导致多线程程序出现非预期结果。

Java内存模型

JVM与计算机的关系

多线程与高并发-part2

JVM抽象

多线程与高并发-part2

线程同步

线程同步机制简介

  1. 线程同步机制是一套用于协调线程之间的数据访问的机制.该机制可以保障线程安全
  2. 同步机制包括:锁、volatile、final、static、以及相关的 API,如 Object.wait()/Object.notify()等

锁概述

  1. 锁可以理解为对共享数据进行保护的一个许可证,一个线程只有在持有许可证(锁)的情况才能对共享数据进行访问,一个锁只能被一个线程持有
  2. 一个线程在访问共享数据之前必须要先获得锁;获得锁的线程被称为锁的持有线程。
  3. 锁具有排他性,就是一个锁一次只能被一个线程只有,这种锁就陈伟排它锁或者互斥锁。
  4. JVM把锁分为内部锁和显示锁。内部锁通过synchronized实现;显示锁通过java.util.concurrent.locks.Lock 接口的实现类实现。

锁的作用

  1. 可以实现对共享数据的安全访问。保证线程的原子性、可见性、有序性
  2. 使用锁保证线程的安全性:
    1. 这些线程在访问共享数据的时候必须使用同一把锁
    2. 即使是读取共享数据的线程也需要使用同步锁。
上一篇:动手学数据分析PART2


下一篇:第四章part2