![](https://img-blog.csdnimg.cn/20201014180756928.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
Java
文章平均质量分 78
峥嵘岁月1
这个作者很懒,什么都没留下…
展开
-
引用类型和基本类型在方法传递中的不同行为
今天在刷lc时,又发现了个小问题。描述如下:红色部分是最开始写的代码,得到满足sum==target的结果后,就将list加入到AllSets这个Arraylist中,一开始觉得没有什么问题,但是运行过后出现了下面的结果:可以看到最终传入allSets中的竟然是两个空列表!这是为什么?发现问题根源:可以看出,这个list 是由其他函数传入的参数,是一个引用类型,所以当我们只是单纯的进行allSets.add(list)时,只是把list的地址传递给了allSets,而list在深度优先搜索的最后,其原创 2021-07-31 21:52:52 · 110 阅读 · 0 评论 -
静态变量和实例变量的存放位置区别问题
昨天在lc平台做算法时,遇到了一个加不加static的问题,即静态变量和实例变量的问题。首先是正确代码及运行结果:上面代码运行击败100%,完全正确,但是将红色部分添加上static修饰之后,会出现以下问题:运行结果在第一个样例即 n = 1 时就报错,且结果中还叠加了 n = 3 的结果,实在是对以下2个问题不解:为什么在第一个样例中会出现了n = 3的运行结果?如果错误,应该也是能通过第一个样例。为什么将brackets修饰成static后,就会出现以上的问题?后台代码的逻辑是什么?在经原创 2021-07-31 15:45:45 · 186 阅读 · 0 评论 -
JVM体系-线程安全和锁优化
线程安全线程安全的定义:当多个线程同时访问一个对象时,如果不用考虑这些线程在运行时环境下的调度和交替执行,也不需要进行额外的同步,或者在调用方进行任何其他的协调操作,调用这个对象的行为都可以获得正确的结果,那就称这个对象是线程安全的。线程安全的代码必备的特征:代码本身封装了所有必要的正确性保障手段,令调用者无须关心多线程下的调用问题,更无 须自己实现任何措施来保证多线程环境下的正确调用。线程安全在Java中的体现:1. 不可变。:只要 一个不可变的对象被正确地构建出来(即没有发生this原创 2021-05-30 14:24:23 · 95 阅读 · 0 评论 -
JVM体系-JVM内存模型与线程
为什么要进行多任务处理?1. 计算机运算能力强大。2. 计算机的运算速度与它的存储和通信子系统的速度差距太大,大量时间花在磁盘I/O、网络通信或者数据库访问上,必须要激发计算机的运算能力,减少造成性能浪费。高速缓存为什么要使用告诉缓存?:计算机的存储设备和处理器的运算速度差距太大,导致计算机需要添加高速缓存来进行一个缓冲。高速缓存的作用:读写速度接近处理器的运算速度,能够将运算所需要的数据复制到缓存中,让运算能快速进行,当运算结束后再从缓存同步回内存中,这样处理器就无需等待缓慢的内存读写..原创 2021-05-30 11:26:18 · 101 阅读 · 0 评论 -
并发编程体系-ThreadLocal
作用:主要是做数据隔离,让每个线程绑定自己的值,即填充的数据只属于当前线程,变量的数据对别的线程而言是相对隔离的,如果你创建了⼀个 ThreadLocal 变量,那么访问这个变量的每个线程都会有这个变量的本地副本,不同线程对这个值的修改并不会互相影响。原理:ThreadLocal本身不存储任何值,内部存在ThreadLocalMap,将ThreadLocal作为key,自己设置的threadLocals作为value进行存储。数据是存在自己线程Thread的threadLocals变量里面的,别人没办法.原创 2021-05-28 21:24:00 · 85 阅读 · 0 评论 -
并发编程体系-semaphore、CountDownLatch、Cyclicbarrier
Semaphore信号量,用来做访问限制,在访问高峰期时,让请求线程阻塞,高峰期过去再释放,限制的仅仅是线程数而不是资源数使用:通过semaphore.acquire()和semaphore.release()来上锁和释放加锁过程–acquire()图解如下:1、当前线程会尝试去同步队列获取一个令牌,获取令牌的过程也就是使用原子的操作去修改同步队列的state ,获取一个令牌则修改为state=state-1。2、 当计算出来的state<0,则代表令牌数量不足,此时会创建一个Node原创 2021-05-27 22:51:02 · 93 阅读 · 0 评论 -
并发编程体系-线程池
**线程池的优点 **1. 降低资源消耗。通过重复利⽤已创建的线程降低线程创建和销毁造成的消耗。2. 提⾼响应速度。当任务到达时,任务可以不需要的等到线程创建就能⽴即执⾏。3. 提⾼线程的可管理性。线程是稀缺资源,如果⽆限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,使⽤线程池可以进⾏统⼀的分配,调优和监控。使用execute()和submit()方法 的区别1. execute() ⽅法⽤于提交不需要返回值的任务,所以⽆法判断任务是否被线程池执⾏成功与否;2. submit() ⽅法.原创 2021-05-27 21:50:18 · 72 阅读 · 0 评论 -
并发编程体系-无锁
无锁的优缺点1. 优点:无锁情况下即使重试失败,线程仍然在高速运行,而synchronized会让线程在没获得锁的情况下发生上下文切换,进入阻塞,等到下次唤醒还得启动线程,所以效率比较低2. 不足:无锁状态下如果没有额外的cpu,虽然不会进入阻塞,但是会没有分到时间片而导致进入可运行状态,还是会导致上下文切换。CAS----CompareAndSet(基于乐观锁)CAS的工作方式:(ref.compareAndSet(prev, excp),CAS首先拿出预期的值来与内存中的值进行比较,即pr.原创 2021-05-27 17:38:05 · 213 阅读 · 0 评论 -
并发编程体系-内存
Java内存模型并发编程的三个重要特性1. 原子性: ⼀个的操作或者多次操作,要么所有的操作全部都得到执⾏并且不会收到任何因素的⼲扰⽽中断,要么所有的操作都执⾏,要么都不执⾏。保证指令不会收到上下文切换的影响。synchronized修饰代码块。2. 可见性:当⼀个变量对共享变量进⾏了修改,那么另外的线程都是⽴即可以看到修改后的最新值。保证指令不会受到cpu缓存的影响。volatile可以保证 共享变量的可见性。synchronized也能保证代码块中的可见性,但是属于重量级操作3. 有序性: .原创 2021-05-27 14:23:06 · 62 阅读 · 0 评论 -
并发编程体系-ReentrantLock
AQS AbstractQueuedSynchronizer,AQS是⼀个⽤来构建锁和同步器的框架,使⽤AQS能简单且⾼效地构造出应⽤⼴泛的⼤量的同步器。AQS的特点:1. 用 state 属性来表示资源的状态(分独占模式和共享模式),用CAS来设置state的状态,独占模式是只有一个线程能够访问资源,而共享模式可以允许多个线程访问资源2. 提供了基于 FIFO 的等待队列,类似于 Monitor 的 EntryList3. 条件变量来实现等待、唤醒机制,支持多个条件变量,类似于 Monit原创 2021-05-26 23:03:44 · 122 阅读 · 0 评论 -
并发编程体系-管程
临界区:一段代码块内如果存在对共享资源的多线程读写操作,称这段代码块为临界区并发访问的线程安全问题多个线程对共享资源进行读写的时候发生指令错乱,比如当A线程对i进行修改,但还未修改时间片就执行完,此时保存当前状态,而B线程对i进行了修改保存后,轮到A执行,A将他的未写入i写入,导致最后结果为A修改的值Synchronized1. synchronized语法:synchronized(对象) // 线程1, 线程2(blocked) { 临界区 } 2. synchronized关键.原创 2021-05-26 17:00:02 · 128 阅读 · 0 评论