Java高级特性
文章平均质量分 89
淡墨@~无痕
这个作者很懒,什么都没留下…
展开
-
JUC并发编程系列详解篇之十八(CPU缓存架构与缓存一致性协议详解)
CPU缓存即高速缓冲存储器,是位于CPU与主内存间的一种容量较小但速度很高的存储器。由于CPU的速度远高于主内存,CPU直接从内存中存取数据要等待一定时间周期,Cache中保存着CPU刚用过或循环使用的一部分数据,当CPU再次使用该部分数据时可从Cache中直接调用,减少CPU的等待时间,提高了系统的效率。原创 2022-10-04 16:13:05 · 292 阅读 · 1 评论 -
JUC并发编程系列详解篇十七(happens-before原则)
happens-before是JMM最核心的概念。对应Java程序员来说,理解happens-before是理解JMM的关键。原创 2022-09-12 23:55:44 · 362 阅读 · 1 评论 -
JUC并发编程系列详解篇十六(java中的其他锁)
无锁,偏向锁,轻量级锁,重量级锁,这四种锁是指锁的状态,专门针对synchronized的。偏向锁通过对比Mark Word解决加锁问题,避免执行CAS操作。而轻量级锁是通过用CAS操作和自旋来解决加锁问题,避免线程阻塞和唤醒而影响性能。重量级锁是将除了拥有锁的线程以外的线程都阻塞。原创 2022-09-12 16:17:34 · 275 阅读 · 0 评论 -
JUC并发编程系列详解篇十五(公平锁VS非公平锁)
ReentrantLock 是一把可重入锁,也是一把互斥锁,它具有与 synchronized 相同的方法和监视器锁的语义,但是它比 synchronized 有更多可扩展的功能。ReentrantLock 的可重入性是指它可以由上次成功锁定但还未解锁的线程拥有。当只有一个线程尝试加锁时,该线程调用 lock() 方法会立刻返回成功并直接获取锁。如果当前线程已经拥有这把锁,这个方法会立刻返回。可以使用 isHeldByCurrentThread 和 getHoldCount 进行检查。原创 2022-09-12 15:56:45 · 337 阅读 · 0 评论 -
JUC并发编程系列详解篇十四(自旋锁 VS 适应性自旋锁)
自旋锁 VS 适应性自旋锁 ,当一个线程尝试去获取某一把锁的时候,如果这个锁此时已经被别人获取(占用),那么此线程就无法获取到这把锁,该线程将会等待,间隔一段时间后会再次尝试获取。这种采用循环加锁 -> 等待的机制被称为自旋锁(spinlock)。原创 2022-09-12 01:41:08 · 289 阅读 · 0 评论 -
JUC并发编程系列详解篇十三(悲观锁VS乐观锁)
在java并发编程中,锁有很多种类,如下图所示:悲观锁乐观锁自旋锁适应性自旋锁无锁偏向锁轻量级锁重量级锁公平锁非公平锁可重入锁不可重入锁共享锁排他锁。原创 2022-09-11 23:57:48 · 311 阅读 · 0 评论 -
JUC并发编程系列详解篇十二(synchronized底层原理进阶)
之后的程序睡眠5秒钟后,程序中t1、t2线程执行代码块时,有意的将其线程睡眠几秒钟,目的在于不管那个线程率先抢到锁,都能让另外一个线程在自旋等待中,所以t1线程打印的是“00”就已经是轻量级锁了,最后看程序执行结果,t2打印的是“10”就已经升级为重量级锁了,显然t2线程已经超过了自旋的最大次数,已经转成重量级锁了。接着线程t1打印了object对象头,可以与第一个打印出来的对象头对比不难发现t1打印的也是偏向锁,但是t1打印的对象头已经把t1的线程id记录在了其对应的23位;原创 2022-09-11 20:04:11 · 577 阅读 · 0 评论 -
JUC并发编程系列详解篇十一(synchronized底层的锁)
操作系统分为“用户空间”和“内核空间”,JVM是运行在“用户态”的,jdk1.6之前,在使用synchronized锁时需要调用底层的操作系统实现,其底层monitor会阻塞和唤醒线程,线程的阻塞和唤醒需要CPU从“用户态”转为“内核态”,频繁的阻塞和唤醒对CPU来说是一件负担很重的工作,这些操作给系统的并发性能 带来了很大的压力。同这个时候CPU就需要从“用户态”切向“内核态”,在这个过程中就非常损耗性能而且效率非常低,所以说jdk1.6之前的synchronized是重量级锁。原创 2022-09-11 01:25:59 · 450 阅读 · 0 评论 -
JUC并发编程系列详解篇十(Synchronized底层原理分析)
synchronized 锁机制在 Java 虚拟机中的同步是基于进入和退出监视器锁对象 monitor 实现的(无论是显示同步还是隐式同步都是如此),每个对象的对象头都关联着一个 monitor 对象,当一个 monitor 被某个线程持有后,它便处于锁定状态。原创 2022-09-11 00:30:16 · 314 阅读 · 0 评论 -
JUC并发编程系列详解篇九(synchronized基础)
在JVM中,对象在内存中的布局分为三块区域:对象头、实例数据和对齐填充。对象头又包括两部分信息,第一部分用于存储对象自身的运行时数据(Mark Word),如HashCode、GC分代年龄、锁状态标志、线程持有的锁、偏向线程ID、偏向时间戳等。对象头的另外一部分是类型指针(Klass pointer),即对象指向它的类元数据的指针,虚拟机通过这个指针来确定这个对象是哪个类的实例。原创 2022-09-10 23:16:14 · 507 阅读 · 0 评论 -
JUC并发编程系列详解篇六(死锁的基本概念)
银行家算法是一种最有代表性的避免死锁的算法。在避免死锁方法中允许进程动态地申请资源,但系统在进行资源分配之前,应先计算此次分配资源的安全性,这就需要引入安全序列来进行判断资源分配是否合理。安全序列是指一个进程序列比如从P1到Pn是安全的,即对于每一个进程Pi(1≤i≤n),它以后尚需要的资源量不超过系统当前剩余资源量与所有进程Pj (j < i )当前占有资源量之和。原创 2022-09-10 14:56:00 · 227 阅读 · 0 评论 -
JUC并发编程系列详解篇五(线程基础理论进阶)
什么是线程安全?当多线程运行了同一代码的时候,如果产生了不同的结果会怎么样?就好比如家里养的鸡下的蛋结果却孵出来一个老鹰,这怎么也显得不合适了,所以线程安全说白了就一句话,当多线程运行同一代码,不会产生不一样的结果。即代码所在的进程中有多个线程在同时运行,而这些线程可能会同时运行这段代码。如果每次运行结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的是一样的,就是线程安全的。在多线程环境中,当各线程不共享数据的时候,即都是私有(private)成员,那么一定是线程安全的。原创 2022-09-10 14:52:36 · 164 阅读 · 0 评论 -
JUC并发编程系列详解篇四(线程基础理论)
这其实是很有意义的,首先多线程的运行和单线程运行相比有很多复杂困难的问题,因为多线程运行充满了未知性,比如说某条线程是否运行,运行了多少时间,线程所期望的数据是否已经赋值完毕,Callable接口的泛型的Future/FutureTask却可以获取多线程运行的结果,可以在等待时间太长没获取到需要的数据的情况下取消该线程的任务。如果线程池的大小超过了处理任务所需要的线程,那么就会回收部分空闲(60秒不执行任务)的线程,当任务数增加时,此线程池又可以智能的添加新线程来处理任务。创建一个单线程的线程池。原创 2022-09-10 14:36:06 · 182 阅读 · 0 评论 -
JUC并发编程系列详解篇三(三大根源性问题)
对于如今的多核处理器,每颗CPU都有自己的缓存,缓存读取的速度非常快,但是缓存仅仅对它所在的处理器可见,CPU缓存与内存的数据不容易保证一致。因此为了避免处理器停顿下来等待向内存写入数据而产生的延迟,处理器使用写缓冲区来临时保存向内存写入的数据。写缓冲区合并对同一内存地址的多次写,并以批处理的方式刷新,也就是说写缓冲区不会即时将数据刷新到主内存中。这个时候缓存不能及时刷新向内存中写入数据,这就导致了可见性问题。原创 2022-09-10 14:05:13 · 116 阅读 · 0 评论 -
JUC并发编程系列详解篇二(并发编程挑战篇)
资源限制是指在进行并发编程时,程序的执行速度受限于计算机硬件资源或软件资源。举例说明:例如,服务器的带宽只有2Mb/s,某个资源的下载速度是1Mb/s每秒,系统启动10个线程下载资源,下载速度不会变成10Mb/s,所以在进行并发编程时,要考虑这些资源的限制。硬件资源限制有带宽的上传/下载速度、硬盘读写速度和CPU的处理速度。软件资源限制有数据库的连接数和socket连接数等。原创 2022-09-10 13:48:07 · 135 阅读 · 0 评论 -
JUC并发编程系列详解篇一(基础)
同步和异步通常来形容一次方法调用,同步方法调用一旦开始,调用者必须等到方法调用返回后,才能继续后续的行为。异步方法调用更像一个消息传递,一旦开始,方法调用就会立即返回,调用者就可以继续后续的操作。而异步方法通常会在另外一个线程中“真实”地执行。整个过程,不会阻碍调用者的工作。如图所示:图中显示了同步方法调用和异步方法调用的区别。对于调用者来说,异步调用似乎是一瞬间就完成的。如果异步调用需要返回结果,那么当这个异步调用真实完成时,则会通知调用者。原创 2022-09-10 01:36:39 · 671 阅读 · 0 评论 -
java虚拟机详解篇十四(java堆内存)
Java堆(Java Heap)是虚拟机所管理的内存中最大的一块。Java堆是被所有线程共享的一块内存区域,在虚拟机启动时创建。此内存区域的唯一目的就是存放对象实例,Java堆是垃圾收集器管理的内存区域。一个JVM实例只存在一个堆内存,所有的对象实例和数组都应该在运行时分配到堆上。堆也是Java内存管理的核心区域。Java堆区在JVM启动的时候即被创建,其空间大小也就确定了。是JVM管理的最大一块内存空间。堆内存的大小是可以调节的。原创 2022-08-24 12:58:00 · 1080 阅读 · 0 评论 -
java虚拟机详解篇十三(本地方法栈)
java的虚拟机栈用于管理java方法的调用,而本地方法栈用于管理本地方法的调用。(本地方法栈线程私有)本地方法栈(Native Method Stacks)与虚拟机栈所发挥的作用是非常相似的,其区别是本地方法栈的使用语言,方式和数据结构并没有强制的规定,可以根据需要自由实现。有的java虚拟机直接把本地方法栈和虚拟机栈合二为一(Hotspot JVM),与虚拟机栈一样,本地方法栈也会在栈深度溢出或者栈扩展失败时分别抛出和异常。原创 2022-08-24 12:50:53 · 1024 阅读 · 0 评论 -
java虚拟机详解篇十二(方法调用和方法的绑定机制)
在jvm中将符号引用为调用方法的直接引用与方法的绑定机制有关,如果方法在在编译期就确定了调用的具体版本,这个版本在运行的时候是不可变的,这样的方法被称之为非虚方法。静态方法,私有方法,final方法,实例构造器,父类方法都是非虚方法。其它的方法被称之为虚方法。1、invokestatic:调用静态方法,解析阶段确定唯一方法版本2、 invokespecial:调用方法、私有及父类方法,解析阶段确定唯一方法版本3、invokevirtual:调用所有虚方法。原创 2022-08-24 00:31:59 · 184 阅读 · 0 评论 -
java虚拟机详解篇十一(java虚拟机栈)
当一个方法开始执行后,只有两种方式退出这个方法。第一种方式是执行引擎遇到任意一个方法返回的字节码指令(return指令),这时候可能会有返回值传递给上层的方法调用者(调用当前方法的方法称为调用者或者主调方法),方法是否有返回值以及返回值的类型将根据遇到何种方法返回指令来决定,这种退出方法的方式称为“正常调用完成”(Normal Method Invocation Completion)。另外一种退出方式是在方法执行的过程中遇到了异常,并且这个异常没有在方法体内得到妥善处理。原创 2022-08-24 00:28:53 · 823 阅读 · 1 评论 -
java虚拟机详解十(程序计数器)
CPU在运行的过程中不断做任务切换,多线程是在一个时间段内只会执行其中的某一个线程的方法,这样必然会有中断和异常,为了准确记录各个线程正在执行的当前字节码指令地址,那就必须每一个线程配备一个PC寄存器,这样线程可以独立计算,不会互相干扰。由于CPU时间片限制,众多线程在并发执行过程中,任何一个确定的时刻,一个处理器或者多核处理器中的一个内核,只会执行某一个线程的字节码指令。:当程序运行时,CPU需要不断切换其他的线程,当CPU切换回原来的线程时,CPU就知道从哪里开始执行。原创 2022-08-24 00:20:22 · 285 阅读 · 0 评论 -
java虚拟机详解篇九(代码编译追踪)
执行偏移地址为14的指令,iload_3指令把存放在第三个局部变量槽中的300入栈到操作数栈,这时操作数栈的值为两个整形数字300,下一条指令imul将操作数栈顶的两个元素出栈,做整形乘法,然后把结果入栈,与iadd指令的执行过程类似。执行偏移地址为2的指令,istore_1指令的作用是操作数栈顶的整形值出栈并存放到第一个局部变量槽中,后续4条指令(一直到偏移地址为11的指令为止)都是做的一样的事情,也就是在对应的代码中把变量a,b,c赋值100,200,300。原创 2022-08-23 15:33:43 · 217 阅读 · 0 评论 -
java虚拟机详解篇八(运行时数据区概述)
Java虚拟机的运行时数据区域。原创 2022-08-23 15:17:02 · 299 阅读 · 0 评论 -
java虚拟机详解篇七(虚拟机线程)
java虚拟机定义了若干程序运行时用到的数据区,其中有一些会随虚拟机的启动而创建,随虚拟机退出而销毁,另外一些则是与线程一一对应,这些与线程对应的数据区域则是随线程的开始和结束而创建和销毁。1、线程是一个程序里的运行单元。JVM允许一个应用有多个线程并行的执行。在Hotspot JVM里,每一个线程都与操作系统的本地线程直接映射。2、当一个java线程准备好执行后,此时一个操作系统的本地线程也同时创建,java线程执行终止后,本地线程也会回收。原创 2022-08-23 14:51:08 · 555 阅读 · 0 评论 -
java虚拟机详解篇六(类的加载机制)
类的加载机制一共有四种,分别是全盘负责机制,父类委托机制,缓存机制,还有最重要的双亲委派机制。原创 2022-08-17 23:55:44 · 223 阅读 · 0 评论 -
java虚拟机详解篇五(类的加载器)
在java程序开发的过程中,类的加载基本上都是由上述三类加载器加载完成,在必要的时候可以自己定义类加载器。1、执行代码前自动验证数字签名2、根据用户提供的密码解密代码,从而实现代码混淆器来避免反编译*.class文件3、根据用户需求来动态地加载类4、根据应用需求把其他数据以字节码的形式加载到应用中。1、隔离加载类2、修改类加载的方式3、扩展加载源4、防止源码泄露。...原创 2022-08-17 17:26:24 · 436 阅读 · 0 评论 -
java虚拟机详解篇四(类的生命周期)
一个类从被加载到虚拟机内存中开始,到卸载出内存为止,它的整个生命周期将会经历加载(Loading)、验证(Verification)、准备(Preparation)、解析(Resolution)、初始化(Initialization)、使用(Using)和卸载(Unloading)七个阶段,其中验证、准备、解析三个部分统称为连接(Linking),如下图所示:需要注意的是,,类型的加载过程必须按照这种顺序按部就班地开始(开始。...原创 2022-08-17 16:29:28 · 359 阅读 · 0 评论 -
java虚拟机详解篇三(JVM和类)
当调用 Java 命令运行某个 Java 程序时,该命令将会启动一个 Java 虚拟机进程,不管该 Java 程序有多么复杂,该程序启动了多少个线程,它们都处于该 Java 虚拟机进程里。在同一个jvm的所有线程,所有变量都处于同一个进程里,它们使用jvm的内存区。不同的jvm内存区信息不共享。......原创 2022-08-16 23:25:22 · 261 阅读 · 0 评论 -
java虚拟机详解篇二(类字节码详解)
class文件本质上是一个以8位字节为基础单位的二进制流,各个数据项目严格按照顺序紧凑的排列在class文件中。jvm根据其特定的规则解析该二进制数据,从而得到相关信息。Class文件采用一种伪结构来存储数据,它有两种类型:无符号数和表。...原创 2022-08-16 21:14:39 · 268 阅读 · 0 评论 -
java的常用设计模式及设计原则详解三(单例模式)
单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。这种模式涉及到一个单一的类原创 2022-04-24 01:50:43 · 452 阅读 · 0 评论