Java内存模型与线程_学习笔记

 2019-12-10 15:45  阅读(1097)
文章分类:Java Core

深入理解java虚拟机: **1、java内存模型** java虚拟机规范中试图定义一种Java内存模型。Java Memory Model(JMM) **1.1 主内存与工作内存** java内存模型规定所有的变量都存储在主内存中(Main Memory)中。 每个线程还有自己的工作内存(working Memory),线程的工作内存保存了该线程使用到的变量的主内存副本拷贝,线程对变量的操作都在工作内存中,而不能直接读写主内存中的变量。 ![20191210001275\_1.png][20191210001275_1.png] **1.2 内存见交互操作** ![20191210001275\_2.png][20191210001275_2.png] ![20191210001275\_3.png][20191210001275_3.png] **1.3 volatile变量的特殊规则** 保证对所有线程有可见性 禁止指令重排优化 **1.4对于long和double型变量的特殊规则** JMM要求1.2中的8个操作具有原子性,但是对于64位数据类型(long double) 允许虚拟机将没有被volatile修饰的64位数据的读写操作划分为两次32位的操作来进行。 即不保证64位数据类型 load store read write这4个操作的原子性。 所有当有多个线程共享未声明位volatile的long或double类型的变量,某些线程就会读到“半个变量”的数值。 **1.5 原子性 可见性 有序性** 原子性:read,load,assign,use,write,synchronized之间的操作 可见性:当一个线程修改了某个变量,其他线程能够立刻得知这个修改。      volatile,synchronized,final均有可见性      同步块的的可见性在于,一个变量执行unlock之前,必须先把此变量同步回主内存中。 有序性:如果在本线程中观察,所有的操作都是有序的。如果在一个线程中观察另一个线程,所有操作都是无序的。 前半句是指:线程内表现为串行语义 后半句是指:指令重排,工作内存与主内存同步延迟 **1.6 先行发生原则** 时间先后顺序与先行发生原则之间基本没有太大关系,所以当我们衡量并发安全问题的时候不要收到时间顺序的干扰,一切必须按照先行发生原则为准。 ![20191210001275\_4.png][20191210001275_4.png] **2 Java与线程** **2.1 线程的实现** 线程式比进程更轻量级的调度执行单位,线程的引入,可以把一个进程的资源分配和执行调度分开,各个线程既可以共享进程资源(内存地址,文件I?O),又可以独立调度。(线程式CPU调度的基本单位) 实现线程有三种方法: **1、使用内核线程实现** 内核线程 Kernel-level Thread,KLT 直接由操作系统内(Kernel)支持的线程。内核通过操纵调度器(Scheduler)对线程进行调度,并将线程的任务映射到各个处理器上。 支持多线程的内核叫多线程内核 multi-Threads kernel 程序不会直接使用内核线程,而且使用内核线程的一种高级接口—轻量级进程 Light Weight Process LWP ![20191210001275\_5.png][20191210001275_5.png] 由于内核线程的支持,每个轻量级进程都成为一个独立的调度单位,及时有一个轻量进程在系统中阻塞,也不会影响到整个进程的工作。 局限性:基于内核线程实现,各种线程操作,例如创建,析构及同步,都需要进行系统调用。 系统调用的代价享队较高,需要在用户态(User Mode)和内核态(Kernel Mode)中来回切换。其次,轻量进程需要下号一定的内核资源,因此一个系统支持轻量级进程的数量是有限的。 **2、使用用户线程实现** 广义上来讲,一个线程只要不是内核线程,就可以认为是用户线程(User Thread),从这个定义来讲,轻量级进程也属于用户进程。 狭义上用户线程指的是完全建立在用户空间的线程库上,系统内核不能感知线程存在的实现。 如果程序实现得当,这种线程不需要切换到内核态,因此操作可以是非常快速且低消耗的,也可以支持规模更大的线程数量,部分高性能数据库中的多线程就是有用户线程实现的。 ![20191210001275\_6.png][20191210001275_6.png] 由于操作系统只能把处理器资源分配到进程,诸如“阻塞如何处理”,“多处理器系统中如何将线程映射到到其他处理器”,这类问题解决起来异常困难,甚至不可完成。 因而使用用户线程实现的程序一般都比较复杂。 **3.使用用户线程加轻量级进程混合实现** 操作系统提供支持的轻量级进程作为用户线程和内核线程之间的桥梁,这样内核提供的线程调度功能及处理器映射,并且用户线程的系统调用要通过轻量级线程来完成,降低整个进程被完全阻塞的风险。 用户线程与轻量级进程的数目比也不一定 N:M ![20191210001275\_7.png][20191210001275_7.png] **2.2、Java线程的实现** **2.3、java线程调度** 线程调度是指系统为线程分配处理器使用权的过程 协同式线程调度 抢占式线程调度 Java线程调度式系统自动完成的,但是建议给线程设置优先级。 状态转换: ![20191210001275\_8.png][20191210001275_8.png] Waiting:处于这个状态的线程不会被分配CPU执行时间,他们要等待被其他线程显示地唤醒。 ![20191210001275\_9.png][20191210001275_9.png] Timed Waiting:处于这个状态的线程不会被分配CPU执行时间,无须等待其他线程显示唤醒。在一定时间之后会由系统自动唤醒。 ![20191210001275\_10.png][20191210001275_10.png] Blocked(阻塞):程序等待进入同步区域的时候,线程处于这种状态。 [20191210001275_1.png]: https://gitee.com/chenssy/blog-home/raw/master/image/series-images/javaCore/javacore/20191210001275_1.png [20191210001275_2.png]: https://gitee.com/chenssy/blog-home/raw/master/image/series-images/javaCore/javacore/20191210001275_2.png [20191210001275_3.png]: https://gitee.com/chenssy/blog-home/raw/master/image/series-images/javaCore/javacore/20191210001275_3.png [20191210001275_4.png]: https://gitee.com/chenssy/blog-home/raw/master/image/series-images/javaCore/javacore/20191210001275_4.png [20191210001275_5.png]: https://gitee.com/chenssy/blog-home/raw/master/image/series-images/javaCore/javacore/20191210001275_5.png [20191210001275_6.png]: https://gitee.com/chenssy/blog-home/raw/master/image/series-images/javaCore/javacore/20191210001275_6.png [20191210001275_7.png]: https://gitee.com/chenssy/blog-home/raw/master/image/series-images/javaCore/javacore/20191210001275_7.png [20191210001275_8.png]: https://gitee.com/chenssy/blog-home/raw/master/image/series-images/javaCore/javacore/20191210001275_8.png [20191210001275_9.png]: https://gitee.com/chenssy/blog-home/raw/master/image/series-images/javaCore/javacore/20191210001275_9.png [20191210001275_10.png]: https://gitee.com/chenssy/blog-home/raw/master/image/series-images/javaCore/javacore/20191210001275_10.png

点赞(0)
版权归原创作者所有,任何形式转载请联系作者; Java 技术驿站 >> Java内存模型与线程_学习笔记

相关推荐