自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(45)
  • 收藏
  • 关注

原创 Java并发编程之ReentrantLock

ReentrantLock相对于 synchronized 它具备如下特点可中断可以设置超时时间可以设置为公平锁支持多个条件变量与 synchronized 一样,都支持可重入基本语法可重入可重入是指同一个线程如果首次获得了这把锁,那么因为它是这把锁的拥有者,因此有权利再次获取这把锁如果是不可重入锁,那么第二次获得锁时,自己也会被锁挡住输出可打断示例输出注意如果是不可中断模式,那么即使使用了 interrupt 也不会让等待中断输出锁超时立刻失败

2021-01-31 22:41:27 157

原创 Java并发编程之活跃性

活跃性死锁有这样的情况:一个线程需要同时获取多把锁,这时就容易发生死锁t1 线程 获得 A对象 锁,接下来想获取 B对象 的锁 t2 线程 获得 B对象 锁,接下来想获取 A对象 的锁 例:结果定位死锁检测死锁可以使用 jconsole工具,或者使用 jps 定位进程 id,再用 jstack 定位死锁:避免死锁要注意加锁顺序另外如果由于某个线程进入了死循环,导致其它线程一直等待,对于这种情况 linux 下可以通过 top 先定位到CPU 占用高的 Java 进程,再利用

2021-01-31 11:32:23 169

原创 Java并发编程之线程状态转换

线程状态转换(从Java角度解释)假设有线程 Thread t情况 1 NEW --> RUNNABLE当调用 t.start() 方法时,由 NEW --> RUNNABLE情况 2 RUNNABLE <–> WAITINGt 线程用 synchronized(obj) 获取了对象锁后调用 obj.wait() 方法时,t 线程从 RUNNABLE --> WAITING调用 obj.notify() , obj.notifyAll() , t.inte

2021-01-31 10:50:45 200

原创 Java并发编程之 Park & Unpark

Park & Unpark基本使用它们是 LockSupport 类中的方法先 park 再 unpark输出先 unpark 再 park输出特点与 Object 的 wait & notify 相比wait,notify 和 notifyAll 必须配合 Object Monitor 一起使用,而 park,unpark 不必park & unpark 是以线程为单位来【阻塞】和【唤醒】线程,而 notify 只能随机唤醒一个等待线程,notify

2021-01-27 17:02:44 1392 1

原创 Java并发编程之设计模式

异步编程之生产者消费者1. 定义要点与前面的保护性暂停中的 GuardObject 不同,不需要产生结果和消费结果的线程一一对应消息队列可以用来平衡生产和消费的线程资源生产者仅负责产生结果数据,不关心数据该如何处理,而消费者专心处理结果数据消息队列是有容量限制的,满时不会再加入数据,空时不会再消耗数据JDK 中各种阻塞队列,采用的就是这种模式2. 实现应用某次运行结果...

2021-01-27 16:42:01 114

原创 Java并发编程之设计模式

同步模式之保护性暂停1. 定义即 Guarded Suspension,用在一个线程等待另一个线程的执行结果要点有一个结果需要从一个线程传递到另一个线程,让他们关联同一个 GuardedObject如果有结果不断从一个线程到另一个线程那么可以使用消息队列(见生产者/消费者)JDK 中,join 的实现、Future 的实现,采用的就是此模式因为要等待另一方的结果,因此归类到同步模式2. 实现应用一个线程等待另一个线程的执行结果执行结果3. 带超时版 GuardedObj

2021-01-27 14:17:23 133

原创 Java并发编程之共享模型

wait notify小故事 - 为什么需要 wait由于条件不满足,小南不能继续进行计算但小南如果一直占用着锁,其它人就得一直阻塞,效率太低于是老王单开了一间休息室(调用 wait 方法),让小南到休息室(WaitSet)等着去了,但这时锁释放开,其它人可以由老王随机安排进屋直到小M将烟送来,大叫一声 [ 你的烟到了 ] (调用 notify 方法)小南于是可以离开休息室,重新进入竞争锁的队列API 介绍obj.wait() 让进入 object 监视器的线程到 wa

2021-01-27 10:32:39 153

原创 Java并发编程之synchronized详解

synchronized详解1. 轻量级锁轻量级锁的使用场景:如果一个对象虽然有多线程要加锁,但加锁的时间是错开的(也就是没有竞争),那么可以使用轻量级锁来优化。轻量级锁对使用者是透明的,即语法仍然是 synchronized假设有两个方法同步块,利用同一个对象加锁创建锁记录(Lock Record)对象,每个线程都的栈帧都会包含一个锁记录的结构,内部可以存储锁定对象的Mark Word让锁记录中 Object reference 指向锁对象,并尝试用 cas 替换 Object 的

2021-01-24 11:46:02 135

原创 Java并发编程之Monitor

MonitorMonitor概念Java对象头以 32 位虚拟机为例普通对象数组对象其中 Mark Word 结构为64 位虚拟机 Mark WordMonitor 原理Monitor 被翻译为监视器或管程每个 Java 对象都可以关联一个 Monitor 对象,如果使用 synchronized 给对象上锁(重量级)之后,该对象头的Mark Word 中就被设置指向 Monitor 对象的指针Monitor 结构如下刚开始 Monitor 中 Owner 为 null

2021-01-24 10:16:12 259

原创 Java并发编程之共享模型

变量的线程安全分析成员变量和静态变量是否线程安全?如果它们没有共享,则线程安全如果它们被共享了,根据它们的状态是否能够改变,又分两种情况如果只有读操作,则线程安全如果有读写操作,则这段代码是临界区,需要考虑线程安全局部变量是否线程安全?局部变量是线程安全的但局部变量引用的对象则未必如果该对象没有逃离方法的作用访问,它是线程安全的如果该对象逃离方法的作用范围,需要考虑线程安全局部变量线程安全分析每个线程调用 test1() 方法时局部变量 i,会在每个线程的栈帧内

2021-01-20 14:52:22 77

原创 Java并发编程之共享模型

线程八锁所谓的“线程八锁”其实就是考察 synchronized 锁住的是哪个对象情况1:12 或 21情况2:1s后12,或 2 1s后 1情况3:3 1s 12 或 23 1s 1 或 32 1s 1情况4:2 1s 后 1情况5:2 1s 后 1情况6:1s 后12, 或 2 1s后 1情况7:2 1s 后 1情况8:1s 后12, 或 2 1s后 1...

2021-01-20 13:59:40 77

原创 数据结构与算法之顺序存储二叉树

顺序存储二叉树顺序存储二叉树的概念基本说明从数据存储来看,数组存储方式和树的存储方式可以相互转换,即数组可以转换成树,树也可以转换成数组,看右面的示意图顺序存储二叉树的特点:1)顺序二叉树通常只考虑完全二叉树2)第n个元素的左子节点为 2 * n + 13)第n个元素的右子节点为 2 * n + 24)第n个元素的父节点为 (n-1) / 2需求:给你一个数组 {1,2,3,4,5,6,7},要求以二叉树前序遍历的方式进行遍历。 前序遍历的结果应当为 1,2,4,5,3,6

2021-01-19 15:11:13 206

原创 Java并发编程之两阶段终止模式

两阶段终止模式在一个线程 T1 中如何“优雅”终止线程 T2?这里的【优雅】指的是给 T2 一个料理后事的机会。1. 错误思路使用线程对象的 stop() 方法停止线程stop 方法会真正杀死线程,如果这时线程锁住了共享资源,那么当它被杀 死后就再也没有机会释放锁,其它线程将永远无法获取锁使用 System.exit(int) 方法停止线程目的仅是停止一个线程,但这种做法会让整个程序都停止2. 两阶段终止模式2.1利用 isInterruptedinterrupt 可以

2021-01-19 11:45:15 313

原创 Java并发编程之Java线程

Java线程线程 API线程状态join 方法详解为什么需要 join下面的代码执行,打印 r 是什么?分析因为主线程和线程 t1 是并行执行的,t1 线程需要 1 秒之后才能算出 r=10而主线程一开始就要打印 r 的结果,所以只能打印出 r=0解决方法用 sleep 行不行?为什么?用 join,加在 t1.start() 之后即可应用之同步(案例1)以调用方角度来讲,如果需要等待结果返回,才能继续运行就是同步不需要等待结果返回,就能继续运行就是异步等

2021-01-19 10:54:45 92

原创 Redis入门

Redis入门Redis 简介Redis 的下载与安装Redis 的基本操作Redis 简介大型翻车现场问题现象海量用户高并发罪魁祸首——关系型数据库性能瓶颈:磁盘IO性能低下扩展瓶颈:数据关系复杂,扩展性差,不便于大规模集群解决思路NosqlNoSQL:即 Not-Only SQL( 泛指非关系型的数据库),作为关系型数据库的补充。作用:应对基于海量用户和海量数据前提下的数据处理问题。特征:可扩容,可伸缩大数据量下高性能灵活的数据模型高可用常见 Nos

2021-01-18 22:01:04 80 1

原创 数据结构与算法之二叉树删除

二叉树删除二叉树-删除节点要求如果删除的节点是叶子节点,则删除该节点如果删除的节点是非叶子节点,则删除该子树.测试,删除掉 5号叶子节点 和 3号子树思路分析代码实现public class Treedemo { public static void main(String[] args) { HeroNode root = new HeroNode(1, "宋江"); HeroNode node2 = new HeroNode(2, "吴用");

2021-01-18 18:32:33 417

原创 数据结构与算法之二叉树查找

二叉树查找二叉树-查找指定节点要求1)请编写前序查找,中序查找和后序查找的方法。2)并分别使用三种查找方式,查找 heroNO = 5 的节点3)并分析各种查找方式,分别比较了多少次思路分析图解代码实现public class Treedemo { public static void main(String[] args) { HeroNode root = new HeroNode(1, "宋江"); HeroNode node2 = new

2021-01-18 16:12:44 263 1

原创 Java并发编程之Java线程

Java线程1.创建和运行线程2.查看线程3.线程 API创建和运行线程方法一,直接使用 Thread例如:输出方法二,使用 Runnable 配合 Thread把【线程】和【任务】(要执行的代码)分开1)Thread 代表线程2)Runnable 可运行的任务(线程要执行的代码)例如:输出Java 8 以后可以使用 lambda 精简代码原理之 Thread 与 Runnable 的关系分析 Thread 的源码,理清它与 Runnable 的关系小结1)

2021-01-18 11:41:22 102

原创 数据结构与算法之二叉树遍历

二叉树遍历遍历前序遍历: 先输出父节点,再遍历左子树和右子树中序遍历: 先遍历左子树,再输出父节点,再遍历右子树后序遍历: 先遍历左子树,再遍历右子树,最后输出父节点小结: 看输出父节点的顺序,就确定是前序,中序还是后序二叉树遍历应用实例代码实现public class Treedemo { public static void main(String[] args) { HeroNode root = new HeroNode(1, "宋江");

2021-01-17 22:23:09 120

原创 数据结构与算法之二叉树概念

二叉树概念树示意图和常用术语树的常用术语(结合示意图理解):1)节点2)根节点3)父节点4)子节点5)叶子节点 (没有子节点的节点)6)节点的权(节点值)7)路径(从root节点找到该节点的路线)8)层9)子树10)树的高度(最大层数)11)森林 :多颗子树构成森林二叉树的概念1)树有很多种,每个节点最多只能有两个子节点的一种形式称为二叉树。2)二叉树的子节点分为左节点和右节点。3)如果该二叉树的所有叶子节点都在最后一层,并且结点总数= 2^n -1 , n 为层数,则

2021-01-17 20:16:05 82

原创 java并发编程之线程与进程

进程与线程1.进程和线程的概念2.并行和并发的概念3.线程基本应用进程和线程进程1)程序由指令和数据组成,但这些指令要运行,数据要读写,就必须将指令加载至 CPU,数据加载至内存。在指令运行过程中还需要用到磁盘、网络等设备。进程就是用来加载指令、管理内存、管理 IO 的2)当一个程序被运行,从磁盘加载这个程序的代码至内存,这时就开启了一个进程。3)进程就可以视为程序的一个实例。大部分程序可以同时运行多个实例进程(例如记事本、画图、浏览器等),也有的程序只能启动一个实例进程(例如网易云音乐、3

2021-01-17 12:12:44 80

原创 JVM之JMM

Java内存模型CAS 与 原子类CASCAS 即 Compare and Swap ,它体现的一种乐观锁的思想,比如多个线程要对一个共享的整型变量执行 +1 操作:获取共享变量时,为了保证该变量的可见性,需要使用 volatile 修饰。结合 CAS 和 volatile 可以实现无锁并发,适用于竞争不激烈、多核 CPU 的场景下。1)因为没有使用 synchronized,所以线程不会陷入阻塞,这是效率提升的因素之一2)但如果竞争激烈,可以想到重试必然频繁发生,反而效率会受影响CAS 底

2021-01-17 10:27:51 106

原创 JVM之JMM

Java内存模型java 内存模型java 内存模型简单的说,JMM 定义了一套在多线程读写共享数据时(成员变量、数组)时,对数据的可见性、有序性、和原子性的规则和保障原子性问题提出,两个线程对初始值为 0 的静态变量一个做自增,一个做自减,各做 5000 次,结果是 0 吗?问题分析以上的结果可能是正数、负数、零。为什么呢?因为 Java 中对静态变量的自增,自减并不是原子操作。例如对于 i++ 而言(i 为静态变量),实际会产生如下的 JVM 字节码指令:而对应 i-- 也是类似:

2021-01-12 23:52:05 214 2

原创 数据结构与算法之存储分析

数组、链表、树的存储分析数组存储方式的分析优点:通过下标方式访问元素,速度快。对于有序数组,还可使用二分查找提高检索速度。缺点:如果要检索具体某个值,或者插入值(按一定顺序)会整体移动,效率较低链式存储方式的分析优点:在一定程度上对数组存储方式有优化(比如:插入一个数值节点,只需要将插入节点,链接到链表中即可, 删除效率也很好)。缺点:在进行检索时,效率仍然较低,比如(检索某个值,需要从头节点开始遍历)树存储方式的分析能提高数据存储,读取的效率, 比如利用 二叉排序树(Binary S

2021-01-11 23:29:30 294

原创 数据结构与算法之哈希表

哈希表介绍散列表(Hash table,也叫哈希表),是根据关键码值(Key value)而直接进行访问的数据结构。也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做散列表。应用看一个实际需求,google公司的一个上机题:有一个公司,当有新的员工来报道时,要求将该员工的信息加入(id,性别,年龄,住址…),当输入该员工的id时,要求查找到该员工的 所有信息.要求: 不使用数据库,尽量节省内存,速度越快越好=>哈希表(散

2021-01-11 23:18:18 130

原创 JVM之类加载

运行期优化即时编译分层编译原因是什么呢?JVM 将执行状态分成了 5 个层次:0 层,解释执行(Interpreter)1 层,使用 C1 即时编译器编译执行(不带 profiling)2 层,使用 C1 即时编译器编译执行(带基本的 profiling)3 层,使用 C1 即时编译器编译执行(带完全的 profiling)4 层,使用 C2 即时编译器编译执行profiling 是指在运行过程中收集一些程序执行状态的数据,例如【方法的调用次数】,【循环的回边次数】等即时编

2021-01-11 18:22:50 90

原创 JVM之类加载

类加载器有层级关系,首先会问问上级是否加载过了(逐层),最后才轮到自定义加载器启动类加载器用 Bootstrap 类加载器加载类:执行输出1)-Xbootclasspath 表示设置 bootclasspath2)其中 /a:. 表示将当前目录追加至 bootclasspath 之后3)可以用这个办法替换核心类java -Xbootclasspath:java -Xbootclasspath/a:<追加路径>java -Xbootclasspath/p:&lt

2021-01-11 16:24:56 89

原创 JVM之类加载

类加载阶段加载将类的字节码载入方法区中,内部采用 C++ 的 instanceKlass 描述 java 类,它的重要 field 有:1)_java_mirror 即 java 的类镜像,例如对 String 来说,就是 String.class,作用是把 klass 暴露给 java 使用2)_super 即父类_fields 即成员变量3)_methods 即方法4)_constants 即常量池5)_class_loader 即类加载器6)_vtable 虚方法表7)_itabl

2021-01-10 23:52:41 82

原创 JVM之类加载

语法糖默认构造器编译成class文件的代码自动拆装箱这段代码在 JDK 5 之前是无法编译通过的,必须改写为泛型集合取值泛型也是在 JDK 5 开始加入的特性,但 java 在编译泛型代码后会执行 泛型擦除 的动作,即泛型信息在编译为字节码之后就丢失了,实际的类型都当做了 Object 类型来处理:所以在取值时,编译器真正生成的字节码中,还要额外做一个类型转换的操作:如果前面的 x 变量类型修改为 int 基本类型那么最终生成的字节码是:还好这些麻烦事都不用自己做。擦除的是字

2021-01-09 13:13:42 62 1

原创 JVM之类加载

字节码技术之 synchronized注意方法级别的 synchronized 不会在字节码指令中有所体现

2021-01-07 12:08:47 56

原创 JVM之类加载

字节码技术之异常处理try-catch1)可以看到多出来一个 Exception table 的结构,[from, to) 是前闭后开的检测范围,一旦这个范围内的字节码执行出现异常,则通过 type 匹配异常类型,如果一致,进入 target 所指示行号2)8 行的字节码指令 astore_2 是将异常对象引用存入局部变量表的 slot 2 位置多个 single-catch 块的情况因为异常出现时,只能进入 Exception table 中一个分支,所以局部变量表 slot 2 位

2021-01-07 11:27:51 59

原创 数据结构与算法之插值查找

插值查找原理介绍1)插值查找算法类似于二分查找,不同的是插值查找每次从自适应mid处开始查找。2)将折半查找中的求mid 索引的公式 , low 表示左边索引left, high表示右边索引right. key 就是前面我们讲的 findVal3)int mid = low + (high - low) * (key - arr[low]) / (arr[high] - arr[low]) ;/插值索引/对应前面的代码公式: int mid = left + (right – left) *

2021-01-06 20:44:19 99

原创 数据结构与算法之二分查找

二分查找请对一个有序数组进行二分查找 {1,8, 10, 89, 1000, 1234} ,输入一个数看看该数组是否存在此数,并且求出下标,如果没有就提示"没有这个数"。思路分析代码实现 public static int erfengSearch(int[] arr,int left,int right,int findValue){ int mid=(left+right)/2; int midValue=arr[mid]; if (left&

2021-01-06 18:17:46 87

原创 数据结构与算法之排序

排序算法总结常用的排序算法对比相关术语解释:1)稳定:如果a原本在b前面,而a=b,排序之后a仍然在b的前面;2)不稳定:如果a原本在b的前面,而a=b,排序之后a可能会出现在b的后面;3)内排序:所有排序操作都在内存中完成;4)外排序:由于数据太大,因此把数据放在磁盘中,而排序通过磁盘和内存的数据传输才能进行;5)时间复杂度: 一个算法执行所耗费的时间。6)空间复杂度:运行完一个程序所需内存的大小。7)n: 数据规模8)k: “桶”的个数9)In-place: 不占用额外内存

2021-01-06 16:40:28 74

原创 JVM之类加载

字节码指令之条件判断指令条件判断指令表几点说明:1)byte,short,char 都会按 int 比较,因为操作数栈都是 4 字节2)goto 用来进行跳转到指定行号的字节码源码字节码循环控制指令源码字节码for循环源码字节码练习 - 判断结果...

2021-01-06 11:22:24 64

原创 JVM之类加载

字节码技术分析a++练习 - 分析 i++目的:从字节码角度分析 a++ 相关题目1)源码2)字节码分析:1.注意 iinc 指令是直接在局部变量 slot 上进行运算2.a++ 和 ++a 的区别是先执行 iload 还是 先执行 iinc...

2021-01-06 10:28:05 62

原创 数据结构与算法之基数排序

基数排序介绍1)基数排序(radix sort)属于“分配式排序”(distribution sort),又称“桶子法”(bucket sort)或bin sort,顾名思义,它是通过键值的各个位的值,将要排序的元素分配至某些“桶”中,达到排序的作用2)基数排序法是属于稳定性的排序,基数排序法的是效率高的稳定性排序法3)基数排序(Radix Sort)是桶排序的扩展4)基数排序是1887年赫尔曼·何乐礼发明的。它是这样实现的:将整数按位数切割成不同的数字,然后按每个位数分别比较。基本思想1)将

2021-01-05 22:21:41 130

原创 JVM之类加载

字节码指令1.入门接着上一节,研究一下两组字节码指令,一个是public cn.itcast.jvm.t5.HelloWorld(); 构造方法的字节码指令2a => aload_0 加载 slot 0 的局部变量,即 this,做为下面的 invokespecial 构造方法调用的参数b7 => invokespecial 预备调用构造方法,哪个方法呢?00 01 引用常量池中 #1 项,即【 Method java/lang/Object."":V 】b1 表示返回另一个

2021-01-05 11:57:57 74

原创 数据结构与算法之排序

快速排序介绍快速排序(Quicksort)是对冒泡排序的一种改进。基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列示意图代码实现public class QuickSortdemo { public static void main(String[] args) { int[] arr={57,-1,0,75,-

2021-01-04 00:44:42 136

原创 数据结构与算法之排序

希尔排序简单插入排序存在的问题我们看简单的插入排序可能存在的问题.数组 arr = {2,3,4,5,6,1} 这时需要插入的数 1(最小), 这样的过程是:{2,3,4,5,6,6}{2,3,4,5,5,6}{2,3,4,4,5,6}{2,3,3,4,5,6}{2,2,3,4,5,6}{1,2,3,4,5,6}结论: 当需要插入的数是较小的数时,后移的次数明显增多,对效率有影响.介绍希尔排序是希尔(Donald Shell)于1959年提出的一种排序算法。希尔排序也是一种插入排

2021-01-03 17:38:23 344

空空如也

空空如也

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

TA关注的人

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