Java成长计划
文章平均质量分 88
JavaBuild888
不在沉默中爆发,就在沉默中灭亡
展开
-
面试官:素有Java锁王称号的‘StampedLock’你知道吗?我:这什么鬼?
相比于传统读写锁多出来的乐观读是StampedLock比 ReadWriteLock 性能更好的关键原因。StampedLock 的乐观读允许一个写线程获取写锁,所以不会导致所有写线程阻塞,也就是当读多写少的时候,写线程有机会获取写锁,减少了线程饥饿的问题,吞吐量大大提高。不过,需要注意的是StampedLock不可重入,不支持条件变量 Condition,对中断操作支持也不友好(使用不当容易导致 CPU 飙升)。原创 2024-04-28 22:17:09 · 753 阅读 · 0 评论 -
Java中的读写锁ReentrantReadWriteLock详解,存在一个小缺陷
读锁是共享锁,写锁是独占锁。在过去学习的过程中我们学过 synchronized、 ReentrantLock这种独占式锁,他们的好处是保证了线程的安全,缺点是同一时刻只能有一个线程持有锁,大大的影响了效率,而之前学过的Semaphore(信号量)这种呢,虽然支持同一时刻被多个线程获取,但它不能很好的保障线程安全性,我们需要的是一种效率高、安全性好的同步锁。,因为在写的时候,是独占模式,其他线程不能读也不能写,这时候若有大量的读操作的话,那这些线程也只能等待着,从而带来写饥饿。那么这个读写锁如何使用呢?原创 2024-04-27 16:05:53 · 504 阅读 · 1 评论 -
大厂高频面试题:ReentrantLock 与 synchronized异同点对比
Condition是 JDK1.5 之后才有的,它具有很好的灵活性,比如可以实现多路通知功能也就是在一个Lock对象中可以创建多个Condition实例(即对象监视器),线程对象可以注册在指定的Condition中,从而可以有选择性的进行线程通知,在调度线程上更加灵活,我们在后面的学习中会耽误聊一聊它!很明显在数据量比较大的时候,竞争激烈时,ReentrantLock的性能要比synchronized好很多,但在数据量较低的情况下,会呈现出不同的结果。如果本篇博客对您有一定的帮助,大家记得。原创 2024-04-21 15:27:12 · 1396 阅读 · 0 评论 -
从源码入手详解ReentrantLock,一个比synchronized更强大的可重入锁
在学习ReentrantLock之前,我们先来复习一下如下的几类锁的定义,这个其实很早的博文中就已经详细的整理过了,这里为了更好理解ReentrantLock锁,还是简单罗列一下。原创 2024-04-21 10:54:50 · 734 阅读 · 0 评论 -
面试官:说一说CyclicBarrier的妙用!我:这个没用过...
在过去的几天里,我们基于AQS学习了不少内容,其中基于AQS构建的同步工具类也学了Semaphore(信号量)和CountDownLatch(倒计时器),甚至于也手撕过同步器,今天我们继续来学习另外一个同步类:CyclicBarrierCyclicBarrier(循环屏障):让一组线程到达一个屏障(也可以叫同步点)时被阻塞,直到最后一个线程到达屏障时,屏障才会开门,所有被屏障拦截的线程才会继续干活。原创 2024-04-15 21:05:58 · 358 阅读 · 0 评论 -
面试官:实战中用过CountDownLatch吗?详细说一说,我:啊这...
在CountDownLatch中通过countDown来减少倒计时数,这是最重要的一个方法,我们继续跟进源码看到它通过releaseShared()方法去释放锁,这个方法是AQS内部的默认实现方法,而在这个方法中再一次的调用了tryReleaseShared(arg),这是一个AQS的钩子方法,方法内部仅有默认的异常处理,真正的实现由CountDownLatch内部类Sync完成。执行结果体现出了倒计时的效果每隔1秒进行3,2,1的倒数;如果本篇博客对您有一定的帮助,大家记得。原创 2024-04-14 14:44:44 · 456 阅读 · 0 评论 -
今天我们来聊一聊Java中的Semaphore
在前面我们讲过的synchronized 和 ReentrantLock 都是一次只允许一个线程访问某个资源,而Semaphore(信号量)可以用来控制同时访问特定资源的线程数量,多线程同时操作共享资源,仍然存在着线程不安全问题,要想多线程安全,理应结合锁进一步保障。原创 2024-04-13 20:03:16 · 669 阅读 · 0 评论 -
美团一面,面试官让介绍AQS原理并手写一个同步器,直接凉了
在上一篇文章中我们就已经提过了AQS是基于 模版方法模式1. 使用者继承 AbstractQueuedSynchronizer 并重写指定的方法;2. 将 AQS 组合在自定义同步组件的实现中,并调用其模板方法,而这些模板方法会调用使用者重写的方法。在模版方法模式下,有个很重要的东西,那就是“钩子方法”,这是一种抽象类中的方法,一般使用 protected 关键字修饰,可以给与默认实现,空方法居多,其内容逻辑由子类实现,为什么不适用抽象方法呢?因为,抽象方法需要子类全部实现,增加大量代码冗余!原创 2024-04-10 18:58:42 · 698 阅读 · 0 评论 -
到底什么是AQS?面试时你能说明白吗!
好啦,到这里我们对于AQS的学习就告一段落啦,后面我们准备使用AQS去自定义一个同步类,持续关注唷😊😊😊。原创 2024-04-03 17:19:35 · 550 阅读 · 0 评论 -
京东一面挂在了CAS算法的三大问题上,痛定思痛不做同一个知识点的小丑
关于CAS算法以及其存在的三大问题到这里就说完了,现在再回头来看,京东这道面试题很简单,然而由于当年的不努力变成了一种遗憾说出,希望小伙伴们能够引以为戒!原创 2024-03-30 08:53:13 · 962 阅读 · 0 评论 -
面试官:小伙子知道synchronized的优化过程吗?我:嘚吧嘚吧嘚,面试官:出去!
会联想的同学,我想已经猜出了大概,首先在Java中的锁都是基于对象的,既然基于对象,那它存在的地方大概率要在对象中,而我们知道在JVM中,对象分为三个部分对象头、实例数据、字节对齐,其中对象头又由Mark Word和Klass Point构成,而Mark Word(标记字段)用于存储对象自身的运行时数据,例如存储对象的HashCode,分代年龄、锁标志位等信息,是synchronized实现轻量级锁和偏向锁的关键。5️⃣进入重量级锁的状态,这个时候,自旋的线程进行阻塞,等待之前线程执行完成并唤醒自己。原创 2024-03-24 21:29:00 · 869 阅读 · 0 评论 -
是时候来唠一唠synchronized关键字了,Java多线程的必问考点!
关于synchronized的介绍其实远没有结束,还有很多细节可以值得学习,我们会在后面的文章中逐渐补充,避免文章过长,读者失去阅读的耐心!原创 2024-03-23 10:28:16 · 723 阅读 · 0 评论 -
您真的了解Java中的锁吗?这7种不同维度下的锁知道吗?
OK,今天关于锁的介绍就写到这里啦,本文先做一个总体上的概括,在后续的更新中会做详细介绍呀!😊。原创 2024-03-20 21:16:04 · 582 阅读 · 0 评论 -
走进volatile的世界,探索它与可见性,有序性,原子性之间的爱恨情仇!
我们定义了2个线程,一个用来求和操作,一个用来赋值操作,因为定义的是成员变量,所以代码(1)(2)(3)(4)之间不存在依赖关系,在运行时极可能发生指令重排序,如将(4)在(3)前执行,顺序为(4)(1)(3)(2),这时输出的就是0而不是4,但在很多性能比较好的电脑上,这种重排序情况不易复现。关键字,这个单词中文释义为:不稳定的,易挥发的,在Java中代表变量修饰符,用来修饰会被不同线程访问和修改的变量,对于方法,代码块,方法参数,局部变量以及实例常量,类常量多不能进行修饰。那这个问题怎么解决呢?原创 2024-03-17 21:43:33 · 1025 阅读 · 0 评论 -
关于volatile与指令重排序的探讨
我们定义了2个线程,一个用来求和操作,一个用来赋值操作,因为定义的是成员变量,所以代码(1)(2)(3)(4)之间不存在依赖关系,在运行时极可能发生指令重排序,如将(4)在(3)前执行,顺序为(4)(1)(3)(2),这时输出的就是0而不是4,但在很多性能比较好的电脑上,这种重排序情况不易复现。OK,知道了这些内容之后,我们再回头看代码示例2中,增加了volatile关键字后的执行顺序,在赋值线程启动后,执行顺序会变成(3)(4)(1)(2),这时打印的结果就为4啦!原创不易,转载请联系Build哥!原创 2024-03-17 21:35:34 · 908 阅读 · 0 评论 -
面试官:volatile如何保证可见性的,具体如何实现?
其实volatile关键字不仅仅能解决可见性问题,还可以通过禁止编译器、CPU 指令重排序和部分 happens-before 规则,解决有序性问题,我们放在下一篇聊。原创 2024-03-16 22:09:18 · 1243 阅读 · 0 评论 -
面试官:小伙子,能聊明白JMM给你SSP!我:嘚吧嘚吧一万字,直接征服面试官!
Java内存模型讲到这里,也就差不多讲完了,其实中间还有缓存一致性协议JSR-133文档volatile等关键字可以展开说一说,但那样篇幅太长,而且内容多乏味,就一笔带过了,感兴趣的小伙伴自己去网上搜一些博文看看吧。原创 2024-03-16 15:40:06 · 757 阅读 · 0 评论 -
一张图搞清楚wait、sleep、join、yield四者区别,面试官直接被征服!
(1)sleep()与wait()的区别?sleep() 是 Thread 类的静态本地方法;wait() 是Object类的成员本地方法;JDK1.8 sleep() wait() 均需要捕获 InterruptedException 异常;sleep() 方法可以在任何地方使用;wait() 方法则只能在同步方法或同步代码块中使用;sleep() 会休眠当前线程指定时间,释放 CPU 资源,不释放对象锁,休眠时间到自动苏醒继续执行;原创 2024-03-14 22:12:34 · 641 阅读 · 0 评论 -
在Java中如何优雅的停止一个线程?可别再用Thread.stop()了!
,这是一种协作机制,当其他线程通知需要被中断的线程后,线程中断的状态被设置为 true,但是具体被要求中断的线程要怎么处理,完全由被中断线程自己决定,可以在合适的时机中断请求,也可以完全不处理继续执行下去,这样一来,安全性就得到了保障。这个方法使用了@Deprecated修饰,代表着它是废弃的方法,在Java的编码规约中,过时的方法不建议继续使用,并且在这个方法的注释中官方也提示说这是一个不安全的强制恶意中断方法,会破坏线程的原子性。Ok,写了那么多,我们来写一个小的demo测试一下线程中断的方法。原创 2024-03-13 11:59:41 · 640 阅读 · 0 评论 -
面试官:线程调用2次start会怎样?我支支吾吾没答上来
OK,今天就讲这么多啦,其实现在回头看看,这仅是一个简单且微小的细节而已,但对于刚准备步入职场的我来说,却是一个难题,今天写出来,除了和大家分享一下Java线程中的小细节外,更多的是希望正在准备面试的小伙伴们,能够心细,多看源码,多问自己为什么?并去追寻答案,Java开发不可浅尝辄止。原创 2024-03-11 20:06:10 · 749 阅读 · 0 评论 -
Java面试必考题之线程的生命周期,结合源码,透彻讲解!
今天关于线程的6种状态就讲到这里啦,这是个重点知识点,希望大家能够铭记于心呀!原创 2024-03-10 20:56:33 · 856 阅读 · 0 评论 -
面试准备不充分,被Java守护线程干懵了,面试官主打一个东西没用但你得会
OK,写到这里,关于守护线程的内容就讲完了,我们从什么是守护线程,守护线程的使用场景,优先级,注意事项等方面,进行了全面的介绍。其实说实话,在我们日后工作中,很少直接使用上守护线程,所以它看似没那么重要,但在很多Java多线程相关的书籍中绝对都有提及,很多小伙伴在学习的过程中认为这个点不重要,也就相当然的忽略了,但遇到变态的面试官,专门挑拣一些偏僻的知识点考你时,难免陷入尴尬,所以希望借助这个考题,大家能够在日后更细心的学习哈。原创 2024-03-09 15:52:27 · 1176 阅读 · 1 评论 -
Java面试挂在线程创建后续,不要再被八股文误导了!创建线程的方式只有1种
在Java中创建线程的方式只有一种:通过Thread.start()调用 start()方法,会启动一个线程并使线程进入就绪状态,当分配到时间片后开始运行。 start() 会执行线程的相应准备工作,然后自动执行 run() 方法的内容原创 2024-03-07 19:40:06 · 562 阅读 · 0 评论 -
面试官让说出8种创建线程的方式,我只说了4种,然后挂了。。。
OK,我们根据面试官的需求,写出了10种创建线程的方式,如果再细分,甚至还可以更多,毕竟线程池的工具类还有没往上写的呢。那么,我们一起静默3分钟,好好思考一下,在Java中创建一个线程的本质,真的是八股文中所说的3种、4种、8种,甚至更多吗?Build哥认为,真正创建线程的方式只有1种,其他的衍生品都算套壳!考虑到本篇已经六七千字了,所以我们在下一篇文章中来分析一下为什么“真正创建线程的方式只有1种!原创 2024-03-07 10:14:47 · 926 阅读 · 0 评论 -
关于Java并发多线程的一点思考
好啦,关于Java并发多线程的思考就写这么多啦🤗。原创 2024-03-05 20:07:03 · 918 阅读 · 0 评论 -
一文讲明白Java中线程与进程、并发与并行、同步与异步
ok,everybody,在过去的两周内,我们大体上讲完了Java的集合,在最后我们探讨了关于HashMap线程不安全的原因,又提出了ConcurrentHashMap这个线程安全的集合解决方案,那么在接下来的2-3周内,我们就一起来学习一下Java中的并发多线程。一个程序至少一个进程,一个进程至少一个线程,进程中的多个线程是共享进程的资源(堆,字符串常量池(JDK1.8)/方法区(JDK1.7));一个进程中有多个线程,多个线程共享进程的堆和方法区资源,但是每个线程有自己的程序计数器,栈区域;原创 2024-03-04 22:50:51 · 716 阅读 · 0 评论 -
面试官:集合使用时应该注意哪些问题?我:应该注意该注意的问题!
以上就是结合开发手册和自己平时开发经验,写的六点注意事项,希望所有小伙伴都能够在日后的开发工作中,保持良好的开发规范与习惯,强烈建议每个人必看《阿里巴巴 Java 开发手册》,这是很多互联网企业,新员工入职必看书籍,虽然里面有些内容,个人感觉有点矫枉过正,但90%以上的约定都非常必要!原创 2024-03-03 23:33:51 · 1177 阅读 · 0 评论 -
为什么HashMap的键值可以为null,而ConcurrentHashMap不行?
这篇文章的时候,漏了一个知识点,知道晚上吃饭的时候才凸显想到,关于ConcurrentHashMap在存储Key与Value的时候,是否可以存null的问题,按理说这是一个小问题,但build哥却不敢忽视,尤其在现在很多面试官都极具挑剔的环境下,万一同学们刷到了咱的博客,回答中遗漏了这个小细节,错过了面试官的考验,那咱可就成罪人了。很多同学们可能会以为ConcurrentHashMap不过是HashMap在多线程环境下的版本,底层实现都一致,只是多了加锁的操作,所以二者对于null的允许程度是一样。原创 2024-03-02 21:42:05 · 1143 阅读 · 0 评论 -
HashMap很美好,但线程不安全怎么办?ConcurrentHashMap告诉你答案!
文章写到这里,ConcurrentHashMap的介绍基本讲完了,我们现在来自我总结一下为啥它的效率又高,又能保证线程安全。Node + CAS + synchronized 保证并发安全,每次上锁的颗粒度细到链表或红黑树的根节点,不会影响其他Node的读写,此外CAS是轻量级的,synchronized 也经过了锁升级;JDK1.7的版本里采用的Segment 分段锁,颗粒度粗不说,Segment 的个数一旦初始化就不能改变。原创 2024-03-02 15:14:53 · 1367 阅读 · 0 评论 -
面试官上来就让手撕HashMap的7种遍历方式,当场愣住,最后只写出了3种
以上就是HashMap中常用的7种遍历方式了,在工作中还是经常用得到的,所以希望小伙伴们能够记住并熟练使用哈。原创 2024-02-29 22:20:03 · 1045 阅读 · 0 评论 -
耗时3天写完的HashMap万字解析,争取一篇文章讲透它,面试官看了都直点头!
哎呀,妈呀!陆陆续续的写了3天,中间老是有工作琐事打断,每天抽空写一点,终于总结完了HashMap,大致的覆盖了HashMap的常见面试题,很多细节可能还是不足,后面有时间了再进行补充哈,多担待。原创 2024-02-27 21:00:22 · 928 阅读 · 0 评论 -
面试官:你知道Comparable 和 Comparator 的区别吗?我:巴拉巴拉
源码就不在这里展示了,爱钻研的小伙伴可以自己去看哈。讲到这里,我们可以对比Comparable接口进行阐述,解释一下为什么有个相似的比较排序接口,还要设计Comparator,因为很多时候我们并不想破坏原始类的结构,比如Person类中,我们只需要它拥有age和name,不想写一些实现方法在其中,这个时候就需要。我们跟进去看一下sort()方法的底层源码,会发现,在它的底层实际上Arrays.sort进行数组排序,而使用的比较器,就是我们传入的自定义PersonalComparator 对象。原创 2024-02-23 18:03:45 · 259 阅读 · 0 评论 -
面试官不按套路出牌,上来就让聊一聊Java中的迭代器(Iterator ),夺命连环问,怎么办?
我们创建一个包含ArrayList容器,里面包含aaa,bbb,ccc元素,通过调用str对象的iterator()方法去遍历元素,然后将遍历的元素打印出来,如上输出(这部分可以手撕给面试官看,方便后续的展开阐述)反编译后我们可以看得出,底层的实现就是迭代器,而这个for-each的写法不过是Java的一个语法糖罢了,这部分属于附加题,讲不明白的,可以不提。当面试官问到这个问题的时候,我们心中一喜,因为他成功的被我们引导到了我们熟悉的方向上,那么接下来,我们要好好唠一唠了!原创 2024-02-21 19:37:42 · 765 阅读 · 0 评论 -
Java集合篇之深度解析Queue,单端队列、双端队列、优先级队列、阻塞队列
作为Queue的子类,它的特点是元素出队顺序是与优先级相关,利用二叉堆的数据结构来实现的,底层使用可变长的数组来存储数据,默认是小顶堆,但可以接收一个 Comparator 作为构造参数,从而来自定义元素优先级的先后。因为队列中的元素是通过小顶堆方式来确定优先级的,而小顶堆是一个完全二叉树,这就导致的队列输出为排序后的结果。队列的特点:存储的元素是有序的、可重复的。作为双端队列的实现类,是基于可变长的数组和双指针来实现,常常被用于实现栈功能,以此来替代曾经那个笨拙的Stack。原创 2024-02-18 22:31:05 · 616 阅读 · 0 评论 -
Java集合篇之set,面试官:请说一说HashSet、LinkedHashSet、TreeSet的区别?
HashSet、LinkedHashSet 和 TreeSet 都是 Set 接口的实现类,都能保证元素唯一,并且都不是线程安全的。HashSet、LinkedHashSet 和 TreeSet 的主要区别在于底层数据结构不同。HashSet 的底层数据结构是哈希表(基于 HashMap 实现)。LinkedHashSet 的底层数据结构是链表和哈希表,元素的插入和取出顺序满足 FIFO。TreeSet 底层数据结构是红黑树,元素是有序的,排序的方式有自然排序和定制排序。原创 2024-02-18 17:52:53 · 1333 阅读 · 0 评论 -
Java集合篇之逐渐被遗忘的Stack,手写一个栈你会吗?
其实在List的继承关系中,除了ArrayList和LinkedList之外,还有另外一个集合类stack(栈),它继承自vector,线程安全,先进后出,随着Java并发编程的发展,它在很多应用场景下被逐渐替代,成为了Java的遗落之类。入栈表示将元素放入栈顶,而出栈表示从栈顶取出元素。在Java的工具包中其实帮我们封装好了一个类,java.util.Stack,它所提供的方法并不多,我们通过一个小示例感受一下。通过上面的代码示例我们了解了一个栈所具备的功能特点,根据它的特点,我们尝试一下手写一个栈!原创 2024-02-18 14:59:38 · 360 阅读 · 0 评论 -
Java集合篇之深入解析LinkedList
作为ArrayList的同门师兄弟,LinkedList的师门地位逊色不少,除了在做算法题的时候我们会用到它之外,在实际的开发工作中我们极少使用它,就连它的创造者都说:“I wrote it,and I never use it”,想想颇有点好笑,但这并不影响我们去学习它,个人认为它底层的链表逻辑对于我们代码思想的培养还是挺有帮助的。我们看过RandomAccess 接口的底层的同学知道,这个接口也是个标识性接口,只要实现了这个接口就意味着支持通过索引访问元素。如果本篇博客对您有一定的帮助,大家记得。原创 2024-02-17 21:21:06 · 1121 阅读 · 0 评论 -
Java集合篇之深入解析ArrayList,这六问你答的上来吗?
二者都是List的实现类,底层都通过object[]数组实现,但Vector是早起JDK支持的集合类,目前几乎全部ArrayList替代,二者有着相似的增删改查功能,但不同的是,Vector的方法都是同步的,可以保证线程安全,而ArrayList则不是,因此,ArrayList相较于Vector拥有良好的性能;,春节期间就是咔咔乱吃,咔咔乱玩,把学习都抛一边子去了,已经9天没有学习了,深深的懊悔,从今天开始,2024年的学习正式开启,一起给我猛冲!不使用泛型的时候,可以添加不同类型元素。原创 2024-02-17 11:41:30 · 632 阅读 · 0 评论 -
盘点Java集合(容器)概览,Collection和Map在开发中谁用的最多?
本文的重心是Java集合的盘点,Collection和Map的引出,各子类的特点比较,针对很多常用的子类并没有展开过多的叙述,后面会按个的学习按个的梳理滴,毕竟这一块内容有非常多的考点,至少得更新个十几篇博文才能讲个大概,继续保持耐心,继续保持学习,一起冲!!!原创 2024-02-07 12:18:23 · 997 阅读 · 0 评论 -
由反射引出的Java动态代理与静态代理
在Java中有多达23种的设计模式(后面Java基础更新完后,会找个时间详细的去写写这些设计模式),恰当的设计模式的使用能够提升代码的效率,简化代码的复杂性。所谓静态代理,一般是针对编译期就已经完成了接口,实现类,代理类的定义,我们对目标对象的增强需要手工去完成,一个目标对象就要有个代理类,非常不灵活。这篇文章中我们讲反射时,曾提到过Java的动态代理中使用了反射技术,那么好,今天我们要就着反射的索引,来学习一下Java中的代理!OK,终于码完了动态代理,自己还去看了很久的源码,头昏脑涨!原创 2024-02-02 17:43:09 · 787 阅读 · 0 评论