自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+

江黎

路漫漫其修远兮,吾将上下而求索

  • 博客(476)
  • 论坛 (1)
  • 问答 (2)
  • 收藏
  • 关注

原创 JVM-运行时内存篇

程序计数器:是一个比较小的内存区域,其主要用于指示当前线程所执行的字节码执行到了第几行,可以理解为是当前线程的行号指示器。字节码解释器在工作时,会通过改变这个计数器的值来取下一条语句指令。 每个程序计数器只用来记录一个线程的行号,所以它是线程私有(一个线程就有一个程序计数器)的。如果程序执行的是一个Java方法,则计数器记录的是正在执行的虚拟机字节码指令地址;如果正在执行的是一个本地(native,由C语言编写完成)方法,则计数器的值为Undefined,由于程序计数器只是记录当前指令地址,所以不存在内

2021-11-22 21:38:13 142

原创 JVM-双亲委派机制

双亲委派机制在java.lang.ClassLoader.loadClass(String,boolean)接口中体现。该接口的逻辑如下:(1)先在当前加载器的缓存中查找有无目标类,如果有,直接返回(2)判断当前加载器的父加载器是否为空,如果不为空,则调用parent.loadClass(name,false)接口进行加载。(3)反之,如果当前加载器的父类加载器为空,则调用findBootstrapClassOrNull(name)接口,让引导类加载器进行加载。(4)如果通过以上3条路径都没能成..

2021-11-21 23:12:38 308

原创 JVM-自定义类加载器

为什么要自定义类加载器?1、隔离加载类在某些框架内进行中间件与应用的模块隔离,把类加载到不同的环境。比如:阿里内某容器框架通过自定义类加载器确保应用中依赖的jar包不会影响到中间件运行时使用的jar包。再比如:Tomcat这类Web应用服务器,内部自定义了好几种类加载器,用于隔离同一个Web应用服务器上的不同应用程序。(类的仲裁-->类冲突)2、修改类加载的方式类的加载模型并非强制,除Bootstrap外,其他的加载并非一定要引入,或者根据实际情况在某个时间点进行按需进行动态加载3、扩展加

2021-11-21 21:42:23 7

原创 JVM-类加载器

类加载器是JVM执行类加载机制的前提。ClassLoader是了Java的核心组件,所有的Class都是由ClassLoader进行加载的,ClassLoader负责通过各种方式将Class信息的二进制数据流读入JVM内部,转换为一个与目标类对应的java.lang.Class对象实例。然后交给Java虚拟机进行链接、初始化等操作。因此,ClassLoader在整个装载阶段,只能影响到类的加载,而无法通过ClassLoader去改变类的链接和初始化行为。至于它是否可以运行,则由Execution E

2021-11-21 00:08:19 282

原创 JVM-类加载

类加载的过程: Loading(装载)阶段 - Linking(链接)阶段 - initialization(初始化)阶段 - using - unloadLoading(装载)阶段所谓装载,简而言之就是将Java类的字节码文件加载到机器内存中,并在内存中构建出Java类的原型--类模板对象。装载阶段,简言之,查找并加载类的二进制数据,生成Class的实例。在加载类时,Java虚拟机必须完成以下3件事情:1、通过类的全限定名,获取类的二进制数据流。2、解析类的二进制数据流为方法区内的数据结构(

2021-11-20 00:02:05 379

原创 JVM-class字节码文件结构概述

Java代码在进行Javac编译的时候,并不像C和C++那样有“连接”这一步骤,而是在虚拟机加class文件的时候进行动态链接。也就是说,在class文件中不会保存各个方法、字段的最终内存布局信息,因此这些字段、方法的符号引用不经过运行期转换的话无法得到真正的内存入口地址,也就无法直接被虚拟机使用。当虚拟机运行时,需要从常量池获得对应的符号引用,再在类加载过程中的解析阶段将其替换为直接引用,并翻译到具体的内存地址之中。这里说明下符号引用和直接引用的区别与关联:符号引用:符号引用以一组符号来描述...

2021-11-19 22:41:47 572

原创 JVM-概述

JVM架构图字节码文件里是什么?源代码经过编译器编译之后便会生成一个字节码文件,字节码是一种二进制的类文件,它的内容是JVM的指令,而不像C、C++经由编译器直接生成机器码前端编译器的种类Java源代码的编译结果是字节码,那么肯定需要有一种编译器能够将]ava源码编译为字节码,承担这个重要责任的就是配置在path环境变量中的javac编译器。javac是一种能够将]ava源码编译为字节码的前端编译器。前端编译器的主要任务就是负责将符合Java语法规范的Java代码转换为符...

2021-11-18 23:47:22 390

原创 前端VUE下载PDF

main.js//配置JS生成PDF的公共函数import html2Canvas from 'html2canvas'import JsPDF from 'jspdf'app.config.globalProperties.getPdf = function() { var title = this.htmlTitle //PDF标题 html2Canvas(document.querySelector('#pdfDom'), { allowTaint: true, taintTe

2021-11-06 14:51:30 19

原创 springboot+vue3+websocket

创建配置类package com.example.emos.api.websocket;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.web.socket.server.standard.ServerEndpointExporter;/** * WebSocke

2021-11-04 23:04:55 49

原创 mysql8之json类型使用

向json类型字段添加数据 json字段为present <update id="updateMeetingPresent" parameterType="HashMap"> UPDATE tb_meeting SET present = JSON_ARRAY_APPEND ( IFNULL( present, JSON_ARRAY() ), '$', #{userId} ) WHERE id = #{meetingId} ..

2021-10-31 09:55:34 17

原创 @Vaule的详细使用

对于从事java开发工作的小伙伴来说,spring框架肯定再熟悉不过了。spring给开发者提供了非常丰富的api,满足我们日常的工作需求。如果想要创建bean实例,可以使用@Controller、@Service、@Repository、@Component等注解。如果想要依赖注入某个对象,可以使用@Autowired和@Resource注解。如果想要开启事务,可以使用@Transactional注解。如果想要动态读取配置文件中的某个系统属性,可以使用@Value注解。等等,还有很多。

2021-10-29 12:09:45 20

原创 Java用递归和遍历实现斐波那契数列

遍历 public static void main(String[] args) { Fibonacci test = new Fibonacci(); System.out.println(test.f(5)); } public int f(int n) { if (n == 1 || n == 2) { return 1; } int first = 1;

2021-10-26 15:39:45 11

原创 @Pattern 为空字符串的时候,不需校验正则表达式

问题 ,使用 @Pattern 注解 在用户 传入 空字符串 ""的时候 也会执行 校验 。租赁类型为非必填项, 当前端 传的 carType:""时 执行了校验如果字段为空,如何告诉系统忽略约束? 这是可选字段,如果它不是空的,才验证它解决方法将空字符串的匹配项添加到正则表达式中 , 如下, 修改正则表达式 加 ^$| @Size(max = 2, message = "carType长度错误") //在service判断 @Pattern(regexp = "...

2021-10-19 21:45:22 47

原创 JUC-StampedLock

StampedLock是JDK1.8中新增的一个读写锁,也是对ReentrantReadWriteLock的优化,乐观读,读的过程中运行获取写锁介入stamp(戳记,long类型),代表了锁的状态。当stamp返回零时,表示线程获取锁失败。并且当释放锁或者转换锁的时候,都要传入最初获取的stamp值锁饥饿问题:ReentrantReadWriteLock实现了读写分离,但是一旦读操作比较多的时候,想要获取写锁就变得比较困难了。假如当前1000个线程,999个读,1个写,有可能999个读取线程

2021-10-17 18:23:53 11

原创 JUC-ReentrantReadWriteLock

ReentrantReadWriteLock:读写锁,一个资源能够被多个读线程访问,或者被一个写线程访问,但是不能同时存在读写线程,读写互斥,读读共享。「读写锁ReentrantReadWrteLock]并不是真正意义上的读写分离,它只允许读读共存,而读写和写写依然是互斥的,大多实际场景是“读/读”线程问并不存在互斤关系,只有”读/写”线程或写/写”线程间的操作需要互斥的。因此引入ReentrantReadwriteLock。一个ReentrantReadWriteLock同时只能存在一个写锁但是可以

2021-10-17 12:19:47 11

原创 JUC-AQS

AQS:AbstractQueuedSynchronizer,抽象的队列同步器,是用来构建锁或者其它同步器组件的重量级基础框架及整个JUC体系的基石,通过内置的FIFO队列来完成资源获取线程的排队工作,并通过一个int类变量(state)表示持有锁的状态CLH:Craig、Landin and Hegersten队列,是一个单向链表,AQS中的队列是CLH变体的虚拟双向队列FIFO。AQS = CLH队列 + state加锁会导致阻塞,有阻塞就需要排队,实现排队必然需要队列。抢到资源的线

2021-10-16 20:38:00 11

原创 JUC-synchronized锁升级

synchronized锁升级无锁 → 偏向锁 → 轻量级锁 → 重量级锁无锁:偏向锁:当一段同步代码一直被同一个线程多次访问,由于只有一个线程那么该线程在后续访问时便会自动获得锁多线程的情况下,锁不仅不存在多线程的竞争,还存在锁由同一线程多次获得的情况,偏向锁就是在这种情况下出现的,它的出现是为了解决只有在一个线程执行同步时提高性能锁的代码块时,不需要再次加锁和释放锁。而是直接比较对象头里面是否存储了指向当前线程的偏向锁。如果相等表示偏向锁是偏向于当前线程的,就不需要再

2021-10-14 23:29:03 43

原创 JUC-内存布局之对象头

在HotSpot虚拟机中,对象在堆内存中的存储布局可以划分为三个部分:对象头(Header)、实例数据(InstanceData)和对齐填充(Padding)。对象头包含对象标记(MarkWord,占8个字节)和类型指针(又叫类元信息,占8个字节)。对齐填充要保证8个字节的倍数。对象头默认...

2021-10-13 23:36:00 13

原创 JUC-ThreadLocal

Thread、ThreadLocal、ThreadLocalMap之间的关系Thread中有ThreadLocalThreadLocalMap是ThreadLocal的静态内部类,Entry是ThreadLocalMap的静态内部类 Enry继承WeakReferenceJVM内部维护了一个线程版的MapthreadLocalMap实际上就是一个以threadLocal实例为key,任意对象为value的Entry对象ThreadLocal的内存泄漏问题及解决1、...

2021-10-12 22:55:59 13

原创 vue-axios传参

get请求,参数是对象 getHospList (page, limit, searchObj) { return request({ url: `/admin/hosp/hospital/list/${page}/${limit}`, method: 'get', params: searchObj }) }, @GetMapping("list/{page}/{limit}") public Result listHos

2021-10-12 12:34:33 11

原创 vscode-setting

{ "emmet.syntaxProfiles": { "vue-html": "html", "vue": "html" }, // vscode默认启用了根据文件类型自动设置tabsize的选项 "editor.detectIndentation": false, // 重新设定tabsize "editor.tabSize": 2, // #每次保存的时候自动格式化 "editor.formatOnSave": true, // #每次保存的时候将.

2021-10-12 12:28:32 17

原创 JUC-ThreadLocal

ThreadLocal用完后要remove必须回收自定义的ThreadLocal变量,尤其在线程池场景下,线程经常会被复用,如果不清理自定义的ThreadLocal变量,可能会影响后续业务逻辑和造成内存泄漏等问题。尽量在代理中使用try-finally块进行回收。/** * @author jl * @since 2021/10/11 19:51 * SimpleDateFormat线程安全问题示例 */public class SimpleDateFormatDemo { p

2021-10-12 08:03:35 8

原创 JUC-LongAdder

LongAdder只能用来计算加法,且从零开始计算LongAccumulator提供了自定义的操作函数普通int+sychronized、AtomicInteger和LongAdder的性能比较public class LongAdderCalcDemo { int num = 0; public synchronized void add_synchronized() { num++; } AtomicInteger atomicInt

2021-10-10 17:05:18 66

原创 JUC-AtomicxxxFieldUpdater

AtomicIntegerFieldUpdater:原子更新对象中int字段的值AtomicLongFieldUpdater:原子更新对象中long字段的值AtomicReferenceFieldUpdater:原子更新引用类型字段的值目的:以一种线程安全的方式操作非线程安全对象内的某些字段使用要求:1、更新的对象属性必须使用public volatile修饰 2、必须使用静态方法newUpdater()创建一个更新器,设置需要更新的类和属性A...

2021-10-10 13:58:28 7

原创 JUC-AtomicMarkableReference

AtomicMarkableReference类是一个线程安全的类,该类封装了一个对象的引用reference和一个布尔值mark,可以原子性地对这两个值进行更新。 定义: public class AtomicMarkableReference<V> exntends Object 其中,V为需要标记的原子操作的类型。 该类的构造方法如下: AtomicMarkableReference( V initialValue,boolean initialMa...

2021-10-10 00:42:29 60

原创 JUC-CountDownLatch与多线程的应用

public class CountDownLatchDemo { private static AtomicInteger a = new AtomicInteger(); public static void main(String[] args) { int count = 50; for (int i = 0; i < count; i++) { new Thread(()->{ .

2021-10-09 23:08:43 59

原创 JUC-自旋锁

自旋锁:spinLock,指尝试获取锁的线程不会立即阻塞,而是采用循环的方式去尝试获取锁,当线程发现锁被占用时,会不断循环判断锁的状态,知道获取。这样的好处是减少线程上下文切换的开销,确点是循环会消耗CPU资源。public class SpinLockDemo { private AtomicReference<Thread> atomicReference = new AtomicReference<>(); public void myLock() {

2021-10-09 21:38:58 9

原创 JUC-CAS

CAS:compare and swap的缩写,比较并交换,实现并发算法时常用到的一种技术。它包含三个操作数:内存位置,预期原值和更新值执行CAS操作的时候,将内存位置的值与预期原值进行比较:如果相同,则将该位置的值更新为新值如果不同,则不作任何操作,多个线程同时执行CAS操作只会有一个成功CAS的核心是Unsafe类,由于Java方法无法直接访问底层系统,需要通过本地Native方法来访问,Unsafe类相当于一个后门,基于该类可以直接操作特定内存的数据。Unsafe类存在于sun.m

2021-10-08 23:43:37 57

原创 JUC-volatile的使用

1、单例模式public class SingletonDemo { // 通过volatile声明,实现线程安全的延迟初始化 private volatile static SingletonDemo singleton; // 私有化构造方法 private SingletonDemo() { } // 双重锁设计 public static SingletonDemo getInstance() { if (sing

2021-10-08 19:06:33 10

原创 JUC-volatile特性

可见性:不保证原子性:多线程环境下,数据计算和数据赋值的操作可能多次出现,即操作非原子。若数据在加载之后,若主内存count变量发生修改之后,由于线程工作内存中的值在此前已经加载,从而不会对变更操作做出相应变化,即私有内存和公共内存中变量不同步,进而导致数据不一致。对于volatile变量,JVM只是保证从主内存加载到线程工作内存的值是最新的,也就是数据加载时是最新的。由此可见,volatile解决的是变量读的可见性问题,但无法保证原子性,对于多线程修改共享变量的场景必须使用加锁同步。.

2021-10-07 23:40:41 18

原创 JUC-volatile变量的读写过程

Java内存模型中定义的8种工作内存与主内存之间的原子操作read(读取)→load(加载)→use(使用)→assign(赋值)→store(存储)→write(写入)→lock(锁定)→unlock(解锁)read:作用于主内存,将变量的值从主内存传输到工作内存,主内存到工作内存。laod:作用于工作内存,将read从主内存传输的变量值放入工作内存变量副本中,即数据加载。use:作用于工作内存,将工作内存变量副本的值传递给执行引擎,每当JVM遇到需要该变量的字节码指令时会执行该操作.

2021-10-07 22:46:04 10

原创 JUC-volatile

volatile的两大特点:1、可见性 2、有序性 (不保证原子性)内存屏障也称内存栅栏,是一类同步屏障指令,是cpu或编译器在对内存随机访问的操作中的一个同步点,使得此点之前的所有读写操作都执行后才可以开始执行此点之后的操作,避免代码重排序。内存屏障其实是一种JVM指令,Java内存模型的重排序规则要求Java编译器在生成JVM指令时插入特定的内存屏障指令,通过这些内存屏障指令,volatile实现了Java内存模型中的可见性和有序性,但volatile无法保证原子性。内存屏障之前的所有写操.

2021-10-07 22:05:57 13

原创 JUC-happens-before先行发生原则

在JMM中,如果一个操作执行的结果需要对另一个操作可见性,或者代码重排序,那么这两个操作之间必须存在happens-before关系。总原则:1、如果一个操作happens-before另一个操作,那么第一个操作的执行结果将对第二个操作可见,而且第一个操作的执行顺序排在第二个操作之前。2、两个操作之间存在happens-before关系,并不意味着一定要按照happens-before原则制定的顺序来执行。如果重排序之后的执行结果已按照happens-before关系来执行的结果一致,那么这种重

2021-10-06 22:54:49 14

原创 JUC-JMM三大特性

JMM(java内存模型,Java Memory model,简称JMM)本身是一种抽象的概念,并不真实存在,它仅仅描述的是一种约定或规范,通过这种规范定义了程序中(尤其是多线程)各个变量的读写访问方式,并决定一个线程对共享变量的写入以及如何变成另一个线程可见,关键技术点都是围绕多线程的原子性、可见性和有序性展开的。原则:JMM的关键技术点都是围绕多线程的原子性,可见性和有序性展开的。能干嘛?1、通过JMM来实现线程和主内存之间的抽象关系。2、屏蔽各个硬件平台和操作系统的内存访问差异,以实.

2021-09-29 23:57:08 11

原创 JUC-LockSupport

正常情况: public static void main(String[] args) { Thread t1 = new Thread(() -> { System.out.println(Thread.currentThread().getName() + " come in"); LockSupport.park(); System.out.println(Thread.currentThrea

2021-09-29 21:45:36 36

原创 JUC-await和signal

正常情况 public static void main(String[] args) { new Thread(()->{ lock1.lock(); try { System.out.println(Thread.currentThread().getName() + " come in"); condition.await();

2021-09-29 19:55:20 11

原创 JUC-wait和notify

Object类中的wait和notify方法实现线程等待和唤醒1、正常情况public class WaitNotifyDemo { static Object lock = new Object(); public static void main(String[] args) { new Thread(()->{ synchronized (lock) { System.out.println(Thr

2021-09-27 23:02:02 7

原创 JUC-线程中断

首先一个线程不应该由其他线程来强制中断或停止,而是应该由线程自己停止。所以Thread.stop,Thread.suspend,Thread.resume都已经被废弃了。其次,在Java中没有办法立即停止一条线程,然而停止线程却尤为重要,如取消一个耗时操作。因此Java提供了一种用于停止线程的中断机制。中断只是一种协作机制,Java没有给中断增加任何语法,中断的过程需要程序员自己实现。若要中断一个线程,你需要手动调用该线程的interrupt方法,该方法也仅仅是将线程对象的中断标识设为true。接着

2021-09-27 21:10:15 29

原创 JUC-死锁

死锁是指两个或两个以上的线程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力干涉他们将都无法推进下去。如果系统资源充足,进程的资源请求都能够得到满足,死锁出现的可能性就很低,否则就会因为争夺有限的资源而陷入死锁。public class DeadLockDemo { static String lockA = "lockA"; static String lockB = "lockB"; public static void main(String[] a.

2021-09-26 23:49:39 15

原创 JUC-可重入锁

隐式锁(即synchronized关键字使用的锁)可重入锁又叫递归锁,指的是可重复可递归调用的锁,在外层使用锁之后,在内层仍然可以获得锁使用并且不发生死锁,这样的锁就叫做可重入锁。 简单的来说就是: 在一个synchronized修饰的方法或代码块的内部调用本类的其他synchronized修饰的方法或代码块时,是永远可以得到的。Java中ReentrantLock和synchronized都是可重入锁,可重入锁能一定程度避免死锁。显式锁(即Lock)也有ReentrantLoc..

2021-09-26 22:38:58 24

空空如也

如何获取swing复选框选中的所有行

发表于 2018-07-30 最后回复 2018-07-30

TA创建的收藏夹 TA关注的收藏夹

TA关注的人 TA的粉丝

提示
确定要删除当前文章?
取消 删除