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中线程的状态即调度关系如下:

(转)《深入理解java虚拟机》学习笔记10——并发编程(二)的更多相关文章

  1. 深入理解java虚拟机学习笔记(一)JVM内存模型

    上周末搬家后,家里的宽带一直没弄好,跟电信客服反映了N遍了终于约了个师傅明天早上来迁移宽带,可以结束一个多星期没网的痛苦日子了.这段时间也是各种忙,都一个星期没更新博客了,再不写之前那种状态和激情都要 ...

  2. 深入理解java虚拟机学习笔记(二)垃圾回收策略

    上篇文章介绍了JVM内存模型的相关知识,其实还有些内容可以更深入的介绍下,比如运行时常量池的动态插入,直接内存等,后期抽空再完善下上篇博客,今天来介绍下JVM中的一些垃圾回收策略.        一. ...

  3. 深入理解java虚拟机学习笔记(二)

    第三章 垃圾收集器与内存分配策略 概述 ​ 程序计数器.虚拟机栈.本地方法栈3个区随线程而生,随线程而灭.因此大体上可认为这几个区域的内存分配和回收都具备确定性.在方法/线程结束时,内存自然就跟着回收 ...

  4. 深入理解Java虚拟机学习笔记(三)-----类文件结构/虚拟机类加载机制

    第6章 类文件结构 1. 无关性 各种不同平台的虚拟机与所有平台都统一使用的程序存储格式——字节码(即扩展名为 .class 的文件) 是构成平台无关性的基石. 字节码(即扩展名为 .class 的文 ...

  5. 深入理解Java虚拟机学习笔记(二)-----垃圾收集器与内存分配策略

    写在前面 本节常见面试题: 如何判断对象是否死亡(两种方法). 简单的介绍一下强引用.软引用.弱引用.虚引用(虚引用与软引用和弱引用的区别.使用软引用能带来的好处). 如何判断一个常量是废弃常量 如何 ...

  6. 深入理解Java虚拟机学习笔记(一)-----Java内存区域

    一 概述 对于 Java 程序员来说,在虚拟机自动内存管理机制下,不再需要像C/C++程序开发程序员这样为内一个 new 操作去写对应的 delete/free 操作,不容易出现内存泄漏和内存溢出问题 ...

  7. 深入理解Java虚拟机 - 学习笔记 1

    Java内存区域 程序计数器 (Program Counter Register) 是一块较小的内存空间,可以看作是当前线程所执行的字节码的行号指示器.在虚拟机的概念模型里,字节码解释器工作时就是通过 ...

  8. 深入理解java虚拟机学习笔记(一)

    第二章 Java内存区域与内存溢出异常 运行时数据区域 程序计数器(Program Counter Register) 程序计数器:当前线程所执行的字节码行号指示器.各条线程之间计数器互不影响,独立存 ...

  9. 《深入理解Java虚拟机》笔记04 -- 并发锁

    Java虚拟机在操作系统层面会先尽一切可能在虚拟机层面上解决竞争关系,尽可能避免真实的竞争发生.同时,在竞争不激烈的场合,也会试图消除不必要的竞争.实现这些手段的方法包括:偏向锁.轻量级锁.自旋锁.锁 ...

随机推荐

  1. ReactNative学习-webView

    在软件内部打开一个网页--不喜欢它没有办法返回,还需要再添加返回按钮== import React from 'react'; import { AppRegistry, Component, Scr ...

  2. Strom实现单词统计代码

    import java.io.File; import java.io.IOException; import java.util.Collection; import java.util.HashM ...

  3. Python练习册--PIL处理图片之加水印

    背景 最近在看到了Python 练习册,每天一个小程序 这个项目,非常有趣,也比较实用. 晚上看了这第000题,关于Python图片处理: 将你的 QQ 头像(或者微博头像)右上角加上红色的数字,类似 ...

  4. GSS6 4487. Can you answer these queries VI splay

    GSS6 Can you answer these queries VI 给出一个数列,有以下四种操作: I x y: 在位置x插入y.D x  : 删除位置x上的元素.R x y: 把位置x用y取替 ...

  5. oc中的分类/协议/属性

    1.分类:当我们想给某个类加一些方法时,如果不想通过继承这个类来实现,可以通过分类给这个类加一些行为,这个过程与继承相比更加轻量化. @interface NSString (SubClass) -( ...

  6. 限额类费用报销单N+1原则

    --添加通过自定义档案列表编码及档案编码查询主键 select bd_defdoc.pk_defdoc as defdoc --查询限额类费用类型主键 from bd_defdoc, bd_defdo ...

  7. ruby学习--varaible

    #全局变量 $global_variable=10 class Class1 def print_global() puts "Global variable in Class1 is #{ ...

  8. DWZ (JUI) 教程 table 排序

    dwz排序是后台排序,不是前台的js排序,他的流程和搜索,分页是一样的,当你点击排序的按钮时,从新发送请求刷新当前的navTable 和 dialog. <th width="60&q ...

  9. ASP.NET缓存 Cache之数据缓存

    添加 Cache[Key]=object  or Cache.Insert 移除 Cache.Remove(key) 1.将值直接写入Cache 代码如下 复制代码 HttpContext.Curre ...

  10. IOS开发: 为UIImageView添加点击事件

    转载于:http://www.pocketdigi.com/20140218/1276.html UIImageView并不像UIButton一样,点点鼠标就可以关联点击事件,也不像Android里有 ...