自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 Java线程池源码解析(ThreadPoolExecutor)

一、简介线程池有降低资源消耗,提高响应速度,提高线程的可管理性的优点。本文以ThreadPoolExecutor类为例,通过阅读源码,分享一下线程池的实现原理。二、源码阅读先来看看继承关系最顶层是一个Executor接口,,就一个 void execute(Runnable command) 方法,代表提交一个任务。public interface Executor { void execute(Runnable command);}接着是ExecutorServic,一般我们定义

2020-05-26 14:47:18 365

原创 最小栈O(1)空间复杂度实现

设计一个支持 push,pop,top 操作,并能在常数时间内检索到最小元素的栈。push(x) – 将元素 x 推入栈中。pop() – 删除栈顶的元素。top() – 获取栈顶元素。getMin() – 检索栈中的最小元素。常见的一道题目,很多解答都是两个栈的做法,这里提供一下O(1)空间复杂度的做法。使用两个栈的原因是,我们pop出最小值的时候,需要将次最小值变成最小值,如果只用一个min来记录最小值,那么无法的到次最小值,那么关键在于,最小值变化的时候,如何得到次最小值?可以维护一个栈

2020-07-02 09:50:51 727

原创 一个有序数组,有重复的数,平方后,数组当中有多少不同的数字

一个有序数组,有重复的数,平方后,数组当中有多少不同的数字?例子,[-1,3,3],返回结果 2.例子,[-1,-1,1,1],返回结果 1.思路:使用双指针,对left和right的绝对值进行比较,如果不相等,那么绝对值大的一边进行收缩,并且不相等的数加一,但是要记录一下这个数的绝对值,这样碰到相同的可以越过去。比如[-1,3,3],一开始right绝对值为3,left绝对值为1,不相等,res为1,记录pre为3,右边向里面收缩一位,然后right绝对值还是3,left绝对值为1,发现right和

2020-07-01 10:16:02 543

原创 找出数组中出现次数大于 N/K 的数

分析数组中出现次数大于 N/K 的数之前,先来看一道简单的题目。1、找出数组中出现次数大于数组长度一半的数分析:1、在数组中一次同时删掉两个不同的元素,如果存在某个数出现次数大于数组长度的一半,那么即使每次都删,最后也会至少剩下 1 个(不可能存在两个候选人,因为不可能存在两个数都超过一半);2、第一个数字作为第一个士兵即候选人 candiate,守阵地;candiate = 1 记录候选人个数;遇到相同元素,count++; 遇到不相同元素,即为敌人,同归于尽,count- -;当遇到 count

2020-06-30 20:24:45 898

原创 CountDownLatch源码分析

一:简介CountDownLatch可以使一个或者多个线程等待其他线程都执行完毕后再执行。CountDownLatch 定义了一个计数器,和一个阻塞队列, 当计数器的值递减为0之前,调用await()的线程处于挂起状态,当计数器递减到0时会唤醒挂起的线程,这里的计数器是一个标志,可以表示一个任务一个线程,也可以表示一个倒计时器,CountDownLatch可以解决那些一个或者多个线程在执行之前必须依赖于某些必要的前提业务先执行的场景。比如,过山车之类的,通常等位置坐满了,再运行。CountDownLa

2020-06-29 15:00:24 102

原创 JUC并发基石之AQS源码解析--共享锁的获取与释放

一:简介前面我们以分析了AQS独占锁的获取与释放,本篇我们来看看共享锁,AQS对于共享锁与独占锁的实现框架还是比较类似的。共享锁与独占锁的区别在于,独占锁是独占的,因此当独占锁已经被某个线程持有时,其他线程只能等待它被释放后,才能去争锁,并且同一时刻只有一个线程能争锁成功。而对于共享锁而言,它可以被多个线程同时持有,因此如果一个线程成功获取了共享锁,那么其他等待在这个共享锁上的线程就也可以尝试去获取锁,而不需要等到该节点释放锁的时候。所以,在共享锁模式下,在获取锁和释放锁结束时,都会唤醒后继节点,这与

2020-06-28 16:31:49 197

原创 读写锁ReentrantReadWriteLock源码分析

一:简介ReentrantReadWriteLock 有两把锁:ReadLock 和 WriteLock,一个读锁一个写锁,合称“读写锁”。其实 ReadLock 和 WriteLock 是靠内部类 Sync 实现的锁。Sync 是 AQS 的一个子类,比如我们分析过的ReentrantLock也是这样的。在 ReentrantReadWriteLock 里面,读锁和写锁的锁主体都是 Sync,但读锁和写锁的加锁方式不一样。读锁是共享锁,写锁是独享锁。读锁的共享锁可保证并发读非常高效,而读写、写写的过程

2020-06-23 10:59:05 85

原创 ReentrantLock各种加锁方式源码分析(公平,非公平,可中断,可定时加锁)

之前我们分析过AbstractQueuedSynchronizer的独占锁的获取与释放的源码,ReentrantLock是基于AbstractQueuedSynchronizer的独占锁实现的锁,今天我们来分析它各种加锁的方式,比如公平锁,非公平锁,可中断加锁,一定时间加锁等。一:公平锁与非公平锁public class ReentrantLock implements Lock, java.io.Serializable { private final Sync sync; //内

2020-06-20 18:19:14 129

原创 JUC并发基石之AQS源码解析--独占锁的释放

JUC并发基石之AQS源码解析–独占锁的获取上一篇文章中,我们分析了独占锁的获取操作, 这篇文章我们来看看独占锁的释放,释放锁的逻辑相对简单,我们来看源码:public final boolean release(int arg) { // 由子类来实现具体的逻辑 if (tryRelease(arg)) { Node h = head; // 头节点不为空 并且waitStates不为0 if

2020-06-19 10:54:01 171

原创 JUC并发基石之AQS源码解析--独占锁的获取

一、简介AQS(AbstractQueuedSynchronizer),抽象队列同步器,是Java中众多的锁以及并发工具的基础,比如ReentrantLock、ReentrantReadWriteLock、CountDownLatch、CyclicBarrier,AQS有独占锁以及共享锁,两种实现,今天,我们来分析AQS获取独占锁的源码。二、源码分析先看看继承关系它继承了AbstractOwnableSynchronizer,实现了序列化的接口。对于AbstractOwnableSynchron

2020-06-17 17:22:01 208

原创 线程池之ScheduledThreadPoolExecutor线程池源码分析

一、简介之前分析过ThreadPoolExecutor这个线程池的源码,Java线程池源码解析(ThreadPoolExecutor),今天来分析它的一个子类ScheduledThreadPoolExecutor,它可以用来实现定时任务,首先思考一下如果是你,你会怎么实现?对于我,我想的是用一个最小堆存储任务,然后线程不断从这个最小堆里面拿任务,对于还没到时间的任务,让线程沉睡响应的时间即可。不过新加入一个任务,看这个任务是否会变成最小堆的堆顶,也就是延迟时间最小的任务,是的话就需要去唤醒线程,更新睡眠

2020-06-16 17:07:22 179

原创 CopyOnWriteArrayList源码

一、简介之前我们分析了ArrayList的源码,但它不是线程安全的,多线程环境下一些问题,比如并发导致数据丢失,并发导致插入null,并发导致数组越界等。所以今天我们来分析线程安全的CopyOnWriteArrayList,CopyOnWrite也就是写时复制。写时复制的思想是当我们往一个容器添加或者删除元素的时候,不直接往当前容器添加,而是将当前容器复制出一个新的容器,然后在新的容器里进行操作,操作完成之后,再将原来容器的引用指向新的容器。这样做的好处就是读写分离,读不加锁,写加锁,读写不冲突,提高并发

2020-05-28 10:33:55 276

原创 【Java集合源码解析】ArrayList源码分析

一、简介ArrayList的底层实现原理是动态数组,所以它需要占据了一块连续的内存空间,其长度就是数组的大小,因为底层是数组,所以ArrayList可以以O(1)的时间复杂度去根据下标访问元素。在每次添加新的元素时,ArrayList都会检查是否需要进行扩容操作,扩容是十分消耗性能的操作,所以知道集合组要多大的容量,再初始化的时候就进行赋值。二、源码阅读先来看看继承关系ArrayList实现了List,提供了基础的添加、删除、遍历等操作。ArrayList实现了RandomAccess,提供了随

2020-05-27 10:27:48 135

原创 线程池shutdown()和shutdownNow()源码解析

一、区别介绍shutdown()当线程池调用该方法时,线程池的状态则立刻变成SHUTDOWN状态。此时,则不能再往线程池中添加任何任务,否则将会抛出RejectedExecutionException异常。但是,此时线程池不会立刻退出,直到添加到线程池中的任务都已经处理完成,才会退出。shutdownNow()执行该方法,线程池的状态立刻变成STOP状态,并试图停止所有正在执行的线程,不再处理还在池队列中等待的任务,当然,它会返回那些未执行的任务。ShutdownNow()并不代表线程池就一定立即就

2020-05-25 22:45:14 609

原创 【Java集合源码解析】LinkedList源码分析

LinkedList 与 ArrayList 一样实现 List 接口,只是 ArrayList 是 List 接口的大小可变数组的实现,LinkedList 是 List 接口链表的实现。基于链表实现的方式使得 LinkedList 在随机插入和删除时更优于 ArrayList,而随机访问则比 ArrayList 逊色些。本文主要通过源码分析 LinkedList。LinkedList 的类结构public class LinkedList<E> extends AbstractSequ

2020-05-22 20:10:04 152

原创 LeetCode378. Kth Smallest Element in a Sorted Matrix解答(值域二分法)

Given a n x n matrix where each of the rows and columns are sorted in ascending order, find the kth smallest element in the matrix.Note that it is the kth smallest element in the sorted order, not the kth distinct element.Example:matrix = [[ 1, 5, 9]

2020-05-13 20:54:23 177

原创 非递归实现二叉树先序,中序和后序遍历(详解)

非递归遍历的实现需要借助“栈”后进先出的特性来保存节点的顺序,前序、中序、后序是相对于根节点而言,根据根节点输出的位置,根、左、右为前序遍历;左、根、右为中序遍历;左、右、根为后序遍历。1) 前序遍历(PreOrder):1.先根节点设为当前节点进行访问2.将当前节点入栈,并将其写入list,循环将左节点入栈,直到左节点为空,3.访问栈顶元素,如果栈顶元素存在右孩子,将右孩子设为当前节点,继续第二步,4.重复第2,3步,直到栈和当前节点都为空对每个结点,都是先遍历其本身,再遍历左子树,所以当从栈

2020-05-12 20:44:06 461

原创 LeetCode236. Lowest Common Ancestor of a Binary Tree解答 (递归)

Given a binary tree, find the lowest common ancestor (LCA) of two given nodes in the tree.According to the definition of LCA on Wikipedia: “The lowest common ancestor is defined between two nodes p and q as the lowest node in T that has both p and q as de

2020-05-12 15:56:10 85

原创 LeetCode199. Binary Tree Right Side View解答(BFS+DFS)

Given a binary tree, imagine yourself standing on the right side of it, return the values of the nodes you can see ordered from top to bottom.For example:Given the following binary tree,Example:Input: [1,2,3,null,5,null,4]Output: [1, 3, 4]Explanation

2020-05-12 12:06:12 103

原创 java基础

1.java重载和重写以及隐藏重载(overload):是一个类中多态性的一种表现,只要方法名 一致 ,但要求每个方法具有不同的参数的类型或参数的个数,方法的返回类型、修饰符可以相同,也可不同。这里需要注意的是,函数重载不能基于返回值类型重写(overriding):1.“两小” :子类方法的返回值类型、抛出的异常 均应小于等于父类方法的2.“两同”:子类方法的方法名、参数列表均应该与父类...

2019-10-21 21:42:47 120

原创 为什么java不要在foreach循环里进行元素的remove/add操作

为什么java不要在foreach循环里进行元素的remove/add操作首先结论是“1”不会报错,但是“2“会出现ConcurrentModificationException(当方法检测到对象的并发修改,但不允许这种修改时就抛出该异常)。从上面我们可以知道是checkForComodification出现的异常,看一下源码final void checkForComodificatio...

2019-08-16 16:57:40 434

原创 JDK1.7的HashMap链表死循环分析

在JDK1.7及以前的版本,如果在并发环境中使用HashMap保存数据,有可能会产生死循环的问题,造成cpu的使用率飙升。产生这个问题是因为JDK1.7及以前的版本中,HashMap扩容采用的是头插入,1.8做的改进是采用尾插法,所以不会造成死循环的问题。 首先,来看1.7扩容的代码: //进行扩容时方法 void resize(int newCapacity) { ...

2019-04-10 22:37:05 2440

转载 mysql并发事务的笔记总结

mysql并发事务的笔记mysql并发事务的笔记总结事务事务的四个性质:原子性,一致性,持久性,隔离性。原子性:事务像一个原子一样不可分割,一个事务中的操作要么全都成功,要么全部失败。一致性:事务执行的结果必须是使数据库从一个一致性状态变到另一个一致性状态。隔离性:一个事务的执行不受到其他事务的干扰。持久性:一个事务一旦提交,它对数据库的数据改变应该是永久的。脏读、不可重复读、幻读...

2018-12-09 19:13:22 124

空空如也

空空如也

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

TA关注的人

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