《深入理解java虚拟机》学习笔记10——并发编程(二)

转载 2013年12月04日 15:36:58

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——并发编程(二)

Java的并发编程是依赖虚拟机内存模型的三个特性实现的: (1).原子性(Atomicity): 原子性是指不可再分的最小操作指令,即单条机器指令,原子性操作任意时刻只能有一个线程,因此是线程安全...

《深入理解java虚拟机》学习笔记9——并发编程(一)

随着多核CPU的高速发展,为了充分利用硬件的计算资源,操作系统的并发多任务功能正变得越来越重要,但是CPU在进行计算时,还需要从内存读取输出,并将计算结果存放到内存中,然而由于CPU的运算速度比内存高...

深入理解Java虚拟机学习笔记——二、垃圾收集器与内存分配策略

1、对象是否存活判定算法 引用计数算法 给对象添加一个引用计数器,当有其他对象引用它时,计数器加1;当引用失效时,计数器减1。任何时刻计数器为0的对象就是不可能在被使用的。引用计数算法实现简单,判...

《深入理解Java虚拟机》学习笔记——内存区域

Java虚拟机在执行程序过程中会把管理的内存划分为不同的shuj
  • xu_fu
  • xu_fu
  • 2014年08月27日 07:22
  • 956

《深入理解java虚拟机》学习笔记8——Tomcat类加载器体系结构

Tomcat 等主流Web服务器为了实现下面的基本功能,都实现了不止一个自定义的类加载器: (1).部署在同一个服务器上的两个web应用程序所使用的java类库可以相互隔离。 (2).部署在同一个...

深入理解Java虚拟机学习笔记——一、JVM结构

1、运行时数据区 JVM在执行Java程序时会将它所管理的内存划分成若干个不同的数据区域,每个区域都有各自的用途以及创建、销毁的时间。有些区域随着JVM虚拟机进程的启动而存在,有些区域则依赖于用户线...

《深入理解java虚拟机》学习笔记3——垃圾回收算法

Java虚拟机的内存区域中,程序计数器、虚拟机栈和本地方法栈三个区域是线程私有的,随线程生而生,随线程灭而灭;栈中的栈帧随着方法的进入和退出而进行入栈和出栈操作,每个栈帧中分配多少内存基本上是在类结构...

《深入理解java虚拟机》学习笔记6——类加载机制

Java虚拟机类加载过程是把Class类文件加载到内存,并对Class文件中的数据进行校验、转换解析和初始化,最终形成可以被虚拟机直接使用的java类型的过程。 在加载阶段,java虚拟机需要完成以...

《深入理解JAVA虚拟机》——学习笔记

出处:http://www.cnblogs.com/gl-developer/p/6502600.html 《深入理解JAVA虚拟机》——学习笔记 JVM内存模型以及分区 ...

《深入理解java虚拟机》学习笔记(1)——走进java

声明:本文及之后的"《深入理解java虚拟机》学习笔记"系列文章以周志明先生编著的《深入理解java虚拟机》第2版为主要依据,结合自身理解与实践,以及其他辅助参考资料进行撰写。本系列文章性质为“学习笔...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:《深入理解java虚拟机》学习笔记10——并发编程(二)
举报原因:
原因补充:

(最多只允许输入30个字)