zoukankan      html  css  js  c++  java
  • (转)《深入理解java虚拟机》学习笔记10——并发编程(二)

    Java的并发编程是依赖虚拟机内存模型的三个特性实现的:

    (1).原子性(Atomicity):

    原子性是指不可再分的最小操作指令,即单条机器指令,原子性操作任意时刻只能有一个线程,因此是线程安全的。

    Java内存模型中通过read、load、assign、use、store和write这6个操作保证变量的原子性操作。

    long和double这两个64位长度的数据类型java虚拟机并没有强制规定他们的read、load、store和write操作的原子性,即所谓的非原子性协定,但是目前的各种商业java虚拟机都把long和double数据类型的4中非原子性协定操作实现为原子性。所以java中基本数据类型的访问读写是原子性操作。

    对于大范围的原子性保证需要通过lock和unlock操作以及synchronized同步块来保证。

    (2).可见性(Visibility):

    可见性是指当一个线程修改了共享变量的值,其他线程可以立即得知这个修改。

    Java内存模型是通过在变量修改后将新值同步回主内存,在变量读取前从主内存刷新变量值来实现可见性的。

    Java中通过volatile、final和synchronized这三个关键字保证可见性:

    volatile:通过刷新变量值确保可见性。

    synchronized:同步块通过变量lock锁定前必须清空工作内存中变量值,重新从主内存中读取变量值,unlock解锁前必须把变量值同步回主内存来确保可见性。

    final:被final修饰的字段在构造器中一旦被初始化完成,并且构造器没有把this引用传递进去,那么在其他线程中就能看见final字段的值,无需同步就可以被其他线程正确访问。

    (3).有序性(Ordering):

    线程的有序性是指:在线程内部,所有的操作都是有序执行的,而在线程之间,因为工作内存和主内存同步的延迟,操作是乱序执行的。

    Java通过volatile和synchronized关键字确保线程之间操作的有序性。

    volatile禁止指令重排序优化实现有序性。

    synchronized通过一个变量在同一时刻只允许一个线程对其进行lock锁定操作来确保有序性。

    JDK线程的实现如下:

    (1).Kernal thread:KLT,内核线程,运行在内核态,是直接有操作系统内核支持的线程,有操作系统内核完成内核线程切换,内核操作线程调度器Threadscheduler对内核线程进行调度,负责将内核线程任务映射到各个处理器上。

    (2).Light weight process: LWP,轻量级用户进程,是编程中传统意义上的线程,每个轻量级进程都由一个内核线程支持。

    (3).User thread:UT,用户线程,运行在用户态,完全由用户空间线程库实现,内核线程无法感知到用户线程的实现,用户线程的创建、同步、调度和销毁完全在用户态中完成,不需要内核态的支持。

    JDK的线程是基于操作系统原生线程模型来实现的,因此JDK版本中线程模型取决于java虚拟机线程与操作系统线程的映射,在不同平台上是不同的。

    线程调度有两种方式:

    (1).协同式:线程的执行时间由线程本身来控制,线程任务执行完成之后主动通知系统切换到另一个线程去执行。

    优点:实现简单,线程切换操作对线程本身是可知的,不存在线程同步问题。

    缺点:线程执行时间不可控制,如果线程长时间执行不让出CPU执行时间可能导致系统崩溃。

    (2).抢占式:每个线程的执行时间有操作系统来分配,操作系统给每个线程分配执行的时间片,抢到时间片的线程执行,时间片用完之后重新抢占执行时间,线程的切换不由线程本身来决定。

    优点:线程执行时间可控制,不会因为一个线程阻塞问题导致系统崩溃。

    当前JDK的多线程是抢占式的多线程系统,但是可以通过设置线程优先级和改变线程的执行时间分配概率。

    注意:由于JDK的线程优先级和操作系统的线程优先级不是一一对应的,因此建议只使用1(最低优先级)、5(正常优先级)和10(最高优先级)这三个优先级。

    另外,线程优先级只是操作系统给线程分配执行时间的概率大小,不是绝对的。

    Java中线程的状态即调度关系如下:

  • 相关阅读:
    c++中的peek函数
    的坑
    Haroopad 写 markdown文本
    《剑指offer》第五十题(字符流中第一个只出现一次的字符)
    《剑指offer》第五十题(字符串中第一个只出现一次的字符)
    《剑指offer》第四十九题(丑数)
    《剑指offer》第四十八题(最长不含重复字符的子字符串)
    《剑指offer》第四十七题(礼物的最大价值)
    《剑指offer》第四十六题(把数字翻译成字符串)
    《剑指offer》第四十五题(把数组排成最小的数)
  • 原文地址:https://www.cnblogs.com/liutoutou/p/4013349.html
Copyright © 2011-2022 走看看