重庆分公司,新征程启航
为企业提供网站建设、域名注册、服务器等服务
本篇内容主要讲解“Java内存模型与线程分别是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Java内存模型与线程分别是什么”吧!
创新互联坚持“要么做到,要么别承诺”的工作理念,服务领域包括:成都做网站、成都网站制作、企业官网、英文网站、手机端网站、网站推广等服务,满足客户于互联网时代的沿河网站设计、移动媒体设计的需求,帮助企业找到有效的互联网解决方案。努力成为您成熟可靠的网络建设合作伙伴!
1、Amdahl定律:通过系统中并行化与串行化的比重来描述多处理器系统能获得的运算加速能力;摩尔定律:用于描述处理器晶体管数量与运行效率之间的发展关系。并发处理的广泛应用是使得Amdahl定律代替摩尔定律成为计算机性能发展源动力的根本原因,也是人类压榨计算机运算能力的最有力武器。
2、衡量一个服务性能的高低好坏,每秒事务处理数(Transaction Per Second,TPS)是最重要的指标之一,它代表着一秒内服务端平均能响应的请求总数,而TPS值与程序的并发能力又有着非常密切的关系。
3、 1)为什么要有高速缓存?解决处理器和内存的速度矛盾——存储设备与处理器的运算速度差几个数量级。但是引入新的问题:缓存一致性。
2)如何解决缓存一致性?需要各个处理器在访问缓存时都遵循一些协议,如:MSI、MESI、MOSI、S有那配色、Firefly及Dragon Protocol等。
3)什么是乱序执行优化?处理器对输入代码进行乱序执行,计算后将乱序执行的结果重组,保证该结果与顺序执行的结果一致,但不保证程序中各个语句计算的先后顺序与输入代码中的顺序一致。Java虚拟机的即时编译也有类似的指令重排优化。
4、内存模型,可以理解为在特定的操作协议下,对特定的内存或高速缓存进行读写访问的过程抽象。
5、JSR:Java Specification Requests,Java规范提案。
6、Java内存模型的主要目标是定义程序中各个变量的访问规则。此处变量包括实例字段、静态字段和构成数组对象的元素,但不包括局部变量与方法参数,因为后者是线程私有的,不会被共享。
7、Java内存模型规定了所有的变量都存储在主内存(Main Memory)中,每条线程还有自己的工作内存(Working Memory),线程的工作内存中保存了被该线程使用到的变量的主内存的副本拷贝,线程对变量的所有操作都必须在工作内存中进行,而不能直接读写主内存中的变量。不同的线程之间也无法直接访问对方工作内存中的变量,线程间变量值的传递均需要通过主内存来完成。这里的主内存和工作内存与Java内存区域中的堆、栈、方法区等并不是同一个层次的内存划分,这两者基本上是没有关系的。
8、Java内存模型定义了8种操作来完成主内存与工作内存的交互,虚拟机实现时必须保证每种操作都是原子的、不可再分的。lock、unlock、read、load、use、assign、store、write。Java内存模型还规定了在执行上述8种基本操作时必须满足的规则。通过这8中基本的内存访问操作和规则就已经完全确定了Java程序中哪些内存访问操作在并发下是安全的。因为定义严谨,实践起来麻烦,可以采用先行发生原则来确定一个访问在并发环境下是否安全。
9、关于volatile型变量的特殊规则:
1)Java虚拟机提供的最轻量级的同步机制;
2)被volatile修改的变量将具备两个特性:
第一是保证变量对所有线程的可见性,但不保证原子性;
第二是禁止指令重排,
3)原理:通过设置内存屏障,即一个lock前缀的空操作,它会将本CPU的Cache写入内存,且该写入操作会将别的CPU或别的内核无效化其Cache,从而达到让volatile变量的修改对其它CPU立即可见,volatile屏蔽指令重排语义在JDK1.5中才被完全修复。
4)Java内存模型对volatile变量定义的特殊规则:a.使用前先取值;b.修改后立即同步;c.不会被指令重排;
5)除了volatile,Java还有两个关键字能够实现可见性,即synchronized和final。
10、Java内存模型是围绕着在并发过程中如何处理原子性、可见性和有序性这三个特征来建立的。
11、先行发生原则
1)它是判断数据是否存在竞争、线程是否安全的主要依据,依靠这个原则,我们可以通过几条规则一揽子解决并发环境下两个操作之间是否可能存在冲突的所有问题。
2)Java内存模型下一些“天然的”发生关系,这些先行发生关系无须借助任何同步器协助就已经存在:
a)程序次序规则。准确的说是控制流顺序而不是程序代码顺序;
b)管程锁定规则。对同一个锁,unlock先行发生于lock操作;
c)volatile变量规则。对于volatile变量,写操作先行发生于读操作;
d)线程启动规则。Thread的start方法先行发生于此线程的每一个动作;
e)线程终止规则。线程的所有操作都先行发生于对此线程的终止检测;
f)线程中断规则。对线程interrupt方法的调用先行发生于被中断线程的代码检测到中断事件的发生;就是说
g)对象终结规则。一个对象的初始化完成先行发生于它的finalize方法的开始。
h)传递性。A先于B,B先于C,则A先于C。
3)时间先后顺序与先行发生原则之间基本没有太大的关系,所以我们衡量并发安全问题的时候不要受到时间顺序的干扰,一切必须以先行发生原则为准。
12、线程的实现
1)线程是比进程更轻量级的调度执行单位,线程引入可以把一个进程的资源分配和调度分开,各个线程既共享进程资源,又可以独立调度;
2)在JavaAPI中,一个native方法往往意味着这个方法没有使用或无法使用平台无关的手段来实现;
3)实现线程的三种方式:使用内核线程实现、使用用户线程实现、使用用户线程加轻量级进程混合实现。
4)使用内核线程实现:
a)内核线程是直接由操作系统内核支持的线程;
b)程序一般不会直接去使用内核线程,而是使用内核线程的一种高级接口——轻量级进程(Light Weight Process, LWP),轻量级进程与内核线程之间是1:1的关系,因此称为一对一线程模型;
c)各种线程操作都需要系统调用,需要在用户态和内核态中来回切换,代价较高,另外每个轻量级进程都需要有一个 内核线程支持,要消耗一定的内核资源;
5)使用用户线程实现:
a)这种线程不需要切换到内核态,因此操作可以非常快速且低消耗,也可以支持规模更大的线程数量;
b)这种进程与用户线程之间1:N的关系称为一对多线程模型;
c)实现比较复杂。
6)使用用户线程加轻量级进程混合实现:用户线程与轻量级进程的数量比是不定的,因此这种N:M的关系称为多对多线程模型;
7)Java线程的实现:Windows平台和Linux平台使用一对一线程模型实现,Solaris平台,提供了专有的虚拟机参数来指定虚拟机使用哪种线程模型。
13、Java线程调度:
1)线程调度是指系统为线程分配处理器使用权的过程,主要有两种方式:协同式调度和抢占式调度。
2)Java使用的线程调度方式是抢占式调度。
3)Java一共设置了10个级别的线程优先级(Thread.MIN_PRIORITY和Thread.MAX_PRIORITY),在两个线程同时处于Ready状态时,优先级越高的线程越容易被系统选择执行。但是线程优先级不太靠谱,不能太依赖优先级。
14、状态转换。Java语言定义了五种线程状态,一个线程只能有且只有其中的一种状态:
New:创建后尚未启动;
Runnable:有可能正在执行,也可能在等待CPU分配执行时间;
Waiting:线程不会被分配CPU执行时间,需要被其它线程显式地唤醒。
Timed Waiting:线程不会被分配CPU执行时间,不过不需要被其它线程显式地唤醒,在一定时间后会由系统自动唤醒;
Blocked:等待锁释放;
Terminated:线程已终止。
15、Java语言中各种操作共享的数据分类5类:不可变、绝对线程安全、相对线程安全、线程兼容和线程对立。相对线程安全就是我们通常意义上所讲的线程安全,单独操作是线程安全的,但涉及到一定顺序的连续执行,需要同步手段保证线程安全。
16、线程安全的实现方法:
1)互斥同步
a)同步是指在多线程并发访问共享数据时,保证共享数据在同一时刻只被一个线程使用;
b)最基本的同步手段就是synchronized。有两点要特别注意:首先synchronized对同一个线程是可重入的,其次同步块在已进入的线程执行完之前,会阻塞后面其它线程的进入,而Java线程是映射到操作系统的原生线程之上的,如果要阻塞或唤醒一个线程,都需要操作系统帮忙完成,这就需要从用户态切换到内核态,因此状态转换需要耗费很多处理器时间;
c)还可以用java.util.concurrent保重的重入锁(ReentrantLock)来实现同步。相比synchronized,ReentrantLock提供了一些高级功能;
d)JDK1.6或以上,性能因素就不再是选择ReentrantLock的理由了,虚拟机在未来的性能改进中也会更偏向与synchronized;
e)互斥同步是一种悲观的并发策略;
2)非阻塞同步 :乐观的并发策略,不需要把线程挂起
3)无同步方案:
a)保证线程安全,并不是一定就要进行同步,两者没有因果关系。
b)可重入代码:天生就是线程安全的。
c)线程本地存储:ThreadLocal,每个线程的Thread对象中都有一个ThreadLocalMap对象,这个对象存储了一组以ThreadLocal.threadLocalHashCode为键,以本地线程变量为值的K-V值对,ThreadLocal对象就是当前线程的ThreadLocalMap的访问入口,每个ThreadLocal对象都包含了一个独一无二的threadLocalHashCode值,使用这个值就可以在线程K-V值对中找回对应的本地线程变量。
17、锁优化技术:适应性自旋,锁消除、锁粗化、轻量级锁、偏向锁
到此,相信大家对“Java内存模型与线程分别是什么”有了更深的了解,不妨来实际操作一番吧!这里是创新互联网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!