- 博客(30)
- 收藏
- 关注
原创 JUC--同步器/CountDown,CyclicBarrier,Semaphore
接下来 Thread-0 竞争成功,permits 再次设置为 0,设置自己为 head 节点,并且 unpark 接下来的共享状态的 Thread-3 节点,但由于 permits 是 0,因此 Thread-3 在尝试不成功后再次进入 park 状态。假设其中 Thread-1,Thread-2,Thread-4 CAS 竞争成功,permits 变为 0,而 Thread-0 和 Thread-3 竞争失败,进入 AQS 队列park 阻塞。这时 Thread-4 释放了 permits,状态如下。
2024-09-30 10:18:22
850
原创 JUC--同步器/ReadWriteLock
t2 读锁解锁,进入 sync.releaseShared(1) 中,调用 tryReleaseShared(1) 让计数减一,但计数还不为零,t3 同样让计数减一,计数为零,进入doReleaseShared() 将头节点从 -1 改为 0 并唤醒下一个节点。😉 这次自己是头节点的临节点,并且没有其他节点竞争,tryAcquire(1) 成功,修改头结点,流程结束。,如果校验通过,表示这期间没有其他线程的写操作,数据可以安全使用,如果校验没通过,需要重新获取读锁,保证数据一致性。
2024-09-30 10:15:45
1083
原创 JUC--同步器/ReentrantLock
开始 Thread-0 持有锁,调用 await,线程进入 ConditionObject 等待,直到被唤醒或打断,调用 await 方法的线程都是持锁状态的,所以说逻辑里。可重入是指同一个线程如果首次获得了这把锁,那么它是这把锁的拥有者,因此有权利再次获取这把锁,如果不可重入锁,那么第二次获得锁时,自己也会被锁挡住,直接造成死锁。:enq 方法中,节点是尾插法,首先赋值的是尾节点的前驱节点,此时前驱节点的 next 并没有指向尾节点,从前遍历会丢失尾节点。
2024-09-30 10:05:17
1015
原创 JUC--同步器/AQS
/独占锁 不可重入@Override// 加上锁 设置 owner 为当前线程@Override //解锁//volatile 修饰的变量放在后面,防止指令重排@Override //是否持有独占锁@Override //加锁(不成功进入等待队列等待)@Override //加锁 可打断@Override //尝试加锁,尝试一次@Override //尝试加锁,带超时@Override //解锁@Override //条件变量。
2024-09-30 10:00:33
943
原创 JUC--无锁
64 位系统中,一个 Cell 为 24 字节(16 字节的对象头和 8 字节的 value),每一个 cache line 为 64 字节,因此缓存行可以存下 2 个的 Cell 对象,当 Core-0 要修改 Cell[0]、Core-1 要修改 Cell[1],无论谁修改成功都会导致当前缓存行失效,从而导致对方的数据失效,需要重新去主存获取,影响效率。,在低并发的时候直接更新,可以保障和 AtomicLong 的性能基本一致,而在高并发的时候通过分散减少竞争,提高了性能。
2024-09-30 09:57:35
636
原创 线程池--任务调度
但是如果本次任务执行出现异常,会进入 setException 方法将任务状态置为异常,把异常保存在 outcome 中,方法返回 false,后续的该任务将不会再周期的执行。Timer 实现定时功能,Timer 的优点在于简单易用,但由于所有任务都是由同一个线程来调度,因此所有任务都是串行执行的,同一时间只能有一个任务在执行,前一个任务的延迟或异常都将会影响到之后的任务。scheduleAtFixedRate():定时执行,一次任务的启动到下一次任务的启动的间隔。
2024-09-30 09:53:44
1034
原创 线程池--工作原理
FutureTask#set:设置正常返回值,首先将任务状态设置为 COMPLETING 状态代表完成中,逻辑执行完设置为 NORMAL 状态代表任务正常执行完成,最后唤醒 get() 阻塞线程。注意:SHUTDOWN 状态也能添加线程,但是要求新加的 Woker 没有 firstTask,而且当前 queue 不为空,所以创建一个线程来帮助线程池执行队列中的任务。:获取任务执行的返回值,执行 run 和 get 的不是同一个线程,一般有多个线程 get,只有一个线程 run。
2024-09-30 09:50:45
1116
原创 线程池--操作Pool
这种系统 CPU 处于阻塞状态,用大部分的时间来处理 I/O 交互,而线程在处理 I/O 的时间段内不会占用 CPU 来处理,这时就可以将 CPU 交出给其它线程使用,因此在 I/O 密集型任务的应用中,我们可以多配置一些线程,具体的计算方法是 2N 或 CPU 核数/ (1-阻塞系数),阻塞系数在 0.8~0.9 之间。maximumPoolSize:最大线程数,当队列中存放的任务达到队列容量时,当前可以同时运行的数量变为最大线程数,创建线程并立即执行最新的任务,与核心线程数之间的差值又叫救急线程数。
2024-09-30 09:47:49
783
原创 线程池--阻塞队列
线程池:一个容纳多个线程的容器,容器中的线程可以重复使用,省去了频繁创建和销毁线程对象的操作降低资源消耗,减少了创建和销毁线程的次数,每个工作线程都可以被重复利用,可执行多个任务提高响应速度,当任务到达时,如果有线程可以直接用,不会出现系统僵死提高线程的可管理性,如果无限制的创建线程,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一的分配,调优和监控线程复用,同一个线程可以被重复使用,来处理多个任务。
2024-09-30 09:37:29
1191
原创 线程安全问题--volatile关键字
使用 volatile 修饰的共享变量,底层通过汇编 lock 前缀指令进行缓存锁定,在线程修改完共享变量后写回主存,其他的 CPU 核心上运行的线程通过 CPU 总线嗅探机制会修改其共享变量为失效状态,读取时会重新从主内存中读取最新的数据。情况四:线程 2 执行 ready = true,切换到线程 1,进入 if 分支为 r.r1 = 0,再切回线程 2 执行 num = 2,发生指令重排。写屏障(sfence,Store Barrier)保证在该屏障之前的,对共享变量的改动,都同步到主存当中。
2024-09-30 09:26:16
732
原创 线程安全问题--基于ObjectMonitor的同步机制
Thread-2 执行完同步代码块的内容,根据 obj 对象头中 Monitor 地址寻找,设置 Owner 为空,把线程栈的锁记录中的对象头的值设置回 MarkWord。synchronized 修饰的方法的不具备继承性,所以子类是线程不安全的,如果子类的方法也被 synchronized 修饰,两个锁对象其实是一把锁,而且是。批量撤销:当撤销偏向锁阈值超过 40 次后,JVM 会觉得自己确实偏向错了,根本就不该偏向,于是整个类的所有对象都会变为不可偏向的,新建的对象也是不可偏向的。
2024-09-30 09:22:58
747
原创 并发基础--java中的线程
interrupt的本质是将线程的打断标记设为true,并调用线程的三个parker对象(C++实现级别)unpark该线程。
2024-09-28 13:29:43
1136
原创 并发基础--进程线程,同步异步,阻塞非阻塞
(concurrent)是同一时间**应对(dealing with)**多件事情的能力(轮流执行线程)。(parallel)是同一时间动手**做(doing)**多件事情的能力(多核同时执行多个线程)。定义:一个进程之内有多个线程,一个线程就是一个指令流,它是系统。在 windows 中进程是不活动的,只是作为线程的容器。进程基本上相互独立的,而线程存在于进程内,是进程的一个子集。进程拥有共享的资源,如内存空间等,供其内部的线程共享。阻塞,非阻塞则描述的是单个线程在调用方法时的“下,通过操作系统中的。
2024-09-28 13:18:13
646
原创 虚拟机字节码执行引擎
Java虚拟机以方法作为最基本的执行单元,“栈帧”(Stack Frame)是用于支持虚拟机进行方法调用和方法执行背后的数据结构,它也是虚拟机运行时数据区中的虚拟机栈(Virtual Machine Stack)的栈元素。
2024-09-28 11:53:18
858
原创 虚拟机类加载机制--类加载
Java虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验、转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这个过程被称作虚拟机的类加载机制。与那些在编译时需要进行连接的语言不同,在Java语言里面,类型的加载、连接和初始化过程都是在程序运行期间完成的,这种策略让Java语言进行提前编译会面临额外的困难,也会让类加载时稍微增加一些性能开销, 但是却为Java应用提供了极高的扩展性和灵活性,Java天生可以动态扩展的语言特性就是依赖运行期动态加载和动态连接这个特点实现的。
2024-09-27 21:35:50
889
原创 JVM监控和故障处理及内存调优
对JVM内存的系统级的调优主要的⽬的是减少GC的频率和Full GC的次数。过多的GC和 Full GC是会占⽤很多的系统资源(主要是CPU),影响系统的吞吐量。使⽤JDK提供的内存查看⼯具,⽐如JConsole和Java VisualVM。jconsole,Java Monitoring and Management Console是从java5开始,在JDK中⾃带的java监控和管理控制台,⽤于对JVM中内存,线程和类等的监控。提 供了实时分析线程、内存,CPU、GC等信息的可视化界⾯。
2024-09-26 16:58:26
304
原创 垃圾收集器与内存分配策略--经典垃圾收集器
图3-6展示了七种作用于不同分代的收集器,如果两个收集器之间存在连线,就说明它们可以搭配使用(jdk 9字样表示在jdk 9时废弃),图中收集器所处的区域,则表示它是属于新生代收集器抑或是老年代收集器。是HotSpot虚拟机运行在客户端模式下的默认新生代收集器历史地位: 最基础、历史最悠久的收集器,曾是JDK 1.3.1之前HotSpot虚拟机新生代收集器的唯一选择。工作方式: 单线程工作,进行垃圾收集时需暂停其他所有工作线程(“Stop The World”)。优点单/少核处理器优势: 在单核/核心数较少
2024-09-26 15:10:10
805
原创 垃圾收集器与内存分配策略--垃圾收集算法
写屏障是一种虚拟机层面的技术,用于在引用类型字段赋值时执行额外动作。它类似于面向切面编程(AOP)中的环绕通知。
2024-09-26 14:55:28
849
原创 垃圾收集器与内存分配策略--垃圾收集概述
垃圾收集(Garbage Collection,下文简称GC)需要完成的三件事情:哪些内存需要回收?什么时候回收?如何回收?第2章介绍了Java内存运行时区域的各个部分,其中程序计数器、虚拟机栈、本地方法栈3个区域的生命周期都是确定的,随线程而生,随线程而灭。栈中的栈帧随着方法的进入和退出而执行对应的入栈和出栈操作。同时,这几个区域所需的空间大小都是确定的,因此这几个区域的内存分配和回收都具备确定性,不需要过多考虑如何回收的问题:当方法结束或者线程结束时,内存自然就跟随着回收了。
2024-09-26 14:44:31
1050
原创 Java内存区域与对象结构探秘--HotSpot虚拟机对象
以最常用的虚拟机HotSpot和最常用的内存区域Java堆为例,深入探讨HotSpot虚拟机在Java堆中对象分配、布局和访问的全过程。
2024-09-26 12:12:28
529
原创 Java内存区域与对象结构探秘--运行时数据区域
数据存储以变量槽(Slot)表示,其中long和double占用两个变量槽,其他类型占用一个。局部变量表所需的空间在编译期分配,运行期间大小不变,大小指的是变量槽的数量。存放基本数据类型、对象引用和returnAddress类型(指令地址)。
2024-09-26 12:07:05
765
原创 确保 Web 安全的 HTTPS
HTTPS 是身披 SSL 外壳的 HTTP。HTTPS 并非是应用层的一种新协议。只是 HTTP 通信接口部分用 SSL(Secure Socket Layer)和 TLS(Transport Layer Security)协议代替而已。
2024-09-26 12:01:54
1135
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人