Java并发 线程安全的三个条件

前言

本篇文章介绍一些多线程的相关的深入概念。理解后对于线程的安全性会有更深的理解。

先说一个格言,摘自Java核心技术:
如果向一个变量写入值,而这个变量接下来可能会被另一个线程读取;或者一个变量读值,而这个变量可能是之前被另一个线程写入的,此时必须同步。

下面就是概念了。

1. Monitor机制:

  • Monitor其实是一种同步工具、同步机制,通常被描述成一个对象,主要特点是:

    1. 同步。
      对象的所有方法都被互斥的执行。好比一个Monitor只有一个运行“许可”,任一个线程进入任何一个方法都需要获得这个“许可”,离开时把许可归还。
    2. 协作。
      通常提供signal机制。允许正持有许可的线程暂时放弃许可,等待某个监视条件成真,条件成立后,当前线程可以通知正在等待这个条件的线程,让它可以重新获得运行许可。
  • 在 Monitor Object 模式中,主要有四种类型参与者:

    1. 监视者对象 Monitor Object
      负责公共的接口方法,这些公共的接口方法会在多线程的环境下被调用执行。
    2. 同步方法
      这些方法是监视者对象所定义。为了防止竞争条件,无论是否有多个线程并发调用同步方法,还是监视者对象还用多个同步方法,在任一事件内只有一个同步方法能够执行。
    3. 监控锁 Monitor Lock
      每一个监视者对象都会拥有一把监视锁。
    4. 监控条件 Monitor Condition
      同步方法使用监视锁和监视条件来决定方法是否需要阻塞或重新执行。
  • Java中,Object 类本身就是监视者对象,Java 对于 Monitor Object 模式做了内建的支持。

    • Object 类本身就是监视者对象
    • 每个 Object 都带了一把看不见的锁,通常叫 内部锁/Monitor 锁/Instrinsic Lock, 这把锁就是 监控锁
    • synchronized 关键字修饰方法和代码块就是同步方法
    • wait()/notify()/notifyAll() 方法构成监控条件(Monitor Condition)

2. Java虚拟机运行时数据区

Java并发 线程安全的三个条件_第1张图片
从Java运行时数据区域我们知道,方法区和堆是由所有线程共享的数据区域。 虚拟机栈、本地方法栈和程序计数器是线程私有的内存。

Java堆内存在线程间共享,下文所说的共享变量即被存储在堆内存中变量:实例域、静态域和数组。
局部变量、方法定义参数和异常处理参数不会在线程之间共享,不会有内存可见性问题,也不受内存模型影响。

3. Java内存模型JMM

Java的并发采用的是共享内存模型,线程间通信是隐式的,同步是显示的;而我们在Android中所常说的Handler通信即采用的是消息传递模型,通信是显示的,同步是隐式的。

  • 并发编程模型的分类
    并发编程中,需要处理两个问题:线程之间如何通信、线程之间如何同步。

    • 通信是指线程之间以何种机制来交换信息。在命令式编程中,线程之间的通信机制有两种:共享内存和消息传递。
      在共享内存的并发模型里,线程之间通过写-读内存中的公共状态来隐式进行通信;而在消息传递模型里,线程之间没有公共状态,必须通过明确的发送信息来显示进行通信。
    • 同步是指程序用于控制不同线程之间操作发生相对顺序的机制。
      在共享内存并发模型里࿰

你可能感兴趣的:(dalvik/art虚拟机,多线程,java,多线程)