自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 JAVA并发编程高级--深入解析 Java ReentrantLock:非公平锁与公平锁的实现原理

是 Java 并发包中的一个可重入的互斥锁,提供了比内置锁()更灵活的锁操作。它支持公平锁和非公平锁两种模式,并且可以尝试非阻塞地获取锁、尝试获取锁并指定等待时间等操作。非公平锁:先尝试通过 CAS 抢锁,抢不到再排队。这种方式可能会导致某些线程长期等待,但吞吐量较高。公平锁:不会尝试直接获取锁,而是先检查队列中是否有等待线程,只有队首线程才允许尝试获取锁。这种方式保证了线程的公平性,但可能会导致吞吐量较低。在实际使用中,可以根据具体需求选择公平锁或非公平锁。如果对响应时间要求较高,建议使用非公平锁;

2025-04-03 12:10:55 582

原创 JAVA并发编程高级--Java AQS 源码:构建并发工具的基石

AQS 是 Java 并发编程的核心框架,通过同步状态和队列机制,实现了高效的线程同步功能。理解 AQS 的源码和原理,对于掌握 Java 并发编程至关重要。希望本文能够帮助读者深入理解 AQS 的内部机制,为学习其他并发工具类(如Semaphore等)打下坚实的基础。

2025-04-03 10:41:03 479

原创 JAVA并发编程高级--LockSupport工具类详解

是Java并发编程中的一个重要工具类,它通过park()和unpark()方法提供了灵活的线程阻塞和唤醒机制。与传统的同步机制相比,更加灵活和安全,适用于复杂的并发场景。通过合理使用,可以实现高效的线程协作和同步控制。希望本文对大家理解有所帮助。如果还有其他问题,欢迎在评论区交流讨论!

2025-03-28 07:30:00 1693

原创 JAVA迭代器的使用

在Java中,迭代器(Iterator)是一种用于遍历集合(如ListSet等)的接口。它提供了一种统一的方式来访问集合中的元素,而无需暴露集合的内部结构。以下是迭代器的基本使用方法和一个示例代码。

2025-03-27 12:02:35 247

原创 JAVA并发编程高级-线程安全集合-CopyOnWriteArrayList

并发包中的并发 List 只有 CopyOnWriteArrayList。CopyOnWriteArrayList是一个线程安全的 ArrayList,对其进行的修改操作都是在底层的一个复制的数组(快照)上进行的,也就是使用了写时复制策略。Copy On WriteArraylist 的类图结构如图 5-1所示。

2025-03-27 11:58:58 772

原创 JAVA并发编程高级——JDK 新增的原子操作类 LongAdder

既然 AtomicLong的性能瓶颈是由于过多线程同时去竞争一个变量的更新而产生的,那么如果把一个变量分解为多个变量,让同样多的线程去竞争多个资源,是不是就解决了性能问题?使用AtomicLong 时,在高并发下大量线程会同时去竞争更新同一个原子变量,但是由于同时只有一个线程的CAS操作会成功,这就造成了大量线程竞争失败后,会通过无限循环不断进行自旋尝试CAS 的操作,而这会白白浪费 CPU 资源。如图 4-1所示,使用 AtomicLong时,是多个线程同时竞争同一个原子变量。

2024-09-29 11:21:53 443

原创 JAVA并发编程高级——原子变量操作类(AtomicLong)

JUC 并发包中包含有 AtomicInteger、AtomicLong 和 AtomicBoolean 等原子性操作类,它们的原理类似,本文讲解 AtomicLong类。Atomicong 是原子性递增或者递减类,其内部使用 Unsafe 来实现,我们看下面的代码。以上是AtomicLong的源码代码(1)通过 Unsafe.getUnsafe()方法获取到 Unsafe 类的实例,这里你可能会有疑问,为何能通过 Unsafe.getUnsafe()方法获取到 Unsafe 类的实例?

2024-09-29 11:18:32 694

原创 JAVA并发编程高级——JAVA并发包中ThreadLocalRandom类原理剖析

本文章首先讲解了 Random的实现原理以及Random 在多线程下需要竞争种子原子变量更新操作的缺点,从而引出ThreadLocalRandom类。ThreadLocalRandom 使用 ThreadLocal的原理,让每个线程都持有一个本地的种子变量,该种子变量只有在使用随机数时才会被初始化。在多线程下计算新种子时是根据自己线程内维护的种子变量进行更新,从而避免了竞争。

2024-09-27 12:11:52 2106

原创 JAVA线程基础二——锁的概述之乐观锁与悲观锁

当一个线程要获取一个被其他线程持有的独占锁时,该线程会被阻塞,那么当一个线程再次获取它自己已经获取的锁时是否会被阻塞呢?如果不被阻塞,那么我们说该锁是可重入的,也就是只要该线程获取了该锁,那么可以无限次数(在高级中我们将知道,严格来说是有限次数)地进入被该锁锁住的代码。下面看一个例子,看看在什么情况下会使用可重入锁。在如上代码中,调用 helloB 方法前会先获取内置锁,然后打印输出。之后调用helloA方法,在调用前会先去获取内置锁,如果内置锁不是可重入的,那么调用线程将会一直被阻塞。

2024-09-25 12:14:05 1697

原创 JAVA线程基础二——伪共享

当CPU访问某个变量时,首先会去看CPUCache内是否有该变量,如果有则直接从中获取,否则就去主内存里面获取该变量,然后把该变量所在内存区域的一个Cache 行大小的内存复制到 Cache 中。由于存放到Cache 行的是内存块而不是单个变量,所以可能会把多个变量存放到一个Cache行中。在该图中,变量x和y同时被放到了CPU的一级和二级缓存,当线程1使用CPU1对变量x进行更新时,首先会修改CPU1的一级缓存变量x所在的缓存行,这时候在缓存一致性协议下,CPU2中变量x对应的缓存行失效。

2024-09-20 11:49:00 325

原创 JAVA线程基础二——Java 指令重排序

答案是不一定,由于代码(1)(2)(3)(4)之间不存在依赖关系,所以写线程的代码(3)(4)可能被重排序为先执行(4)再执行(3),那么执行(4)后,读线程可能已经执行了(1)操作,并且在(3)执行前开始执行(2)操作,这时候输出结果为 0 而不是 4。在如上代码中,变量c的值依赖a和b的值,所以重排序后能够保证(3)的操作在(2)(1)之后,但是(1)(2)谁先执行就不一定了,这在单线程下不会存在问题,因为并不影响最终结果。

2024-09-20 11:39:44 484

原创 JAVA线程基础二——CAS 实现(Unsafe类)

JDK的rt.jar 包中的 Unsafe 类提供了硬件级别的原子性操作,Unsafe 类中的方法都是native 方法,它们使用JNI的方式访问本地C++实现库。下面我们来了解一下 Unsafe 提供的几个主要的方法以及编程时如何使用 Unsafe 类做一些事情。下面是JDK8新增的函数,这里只列出 Long 类型操作。

2024-09-20 10:47:57 1111

原创 JAVA线程基础二——原子性操作

使用 synchronized 关键字的确可以实现线程安全性,即内存可见性和原子性,但是synchronized 是独占锁,没有获取内部锁的线程会被阻塞掉,而这里的 getCount 方法只是读操作,多个线程同时调用不会存在线程安全问题。答案是肯定的,下面将讲到的在内部使用非阻塞CAS算法实现的原子性操作类AtomicLong 就是一个不错的选择。所谓原子性操作,是指执行一系列操作时,这些操作要么全部执行,要么全部不执行不存在只执行其中一部分的情况。那么如何才能保证多个操作的原子性呢?

2024-09-14 10:35:06 390

原创 JAVA线程基础二——CAS 操作

敬请期待。

2024-09-14 10:33:59 124

原创 JAVA线程基础——synchronized关键字和volatile关键字

synchronized 块是 Java 提供的一种原子性内置锁,Java中的每个对象都可以把它当作一个同步锁来使用,这些Java内置的使用者看不到的锁被称为内部锁,也叫作监视器锁。线程的执行代码在进入 synchronized 代码块前会自动获取内部锁,这时候其他线程访问该同步代码块时会被阻塞挂起。拿到内部锁的线程会在正常退出同步代码块或者抛出异常后或者在同步块内调用了该内置锁资源的wait 系列方法时释放该内置锁。内置锁是排它锁,也就是当一个线程获取这个锁后,其他线程必须等待该线程释放锁后才能获取该锁。

2024-09-13 11:16:40 951

原创 JAVA线程基础二——并发编程基础知识

首先要澄清并发和并行的概念,并发是指同一个时间段内多个任务同时都在执行,并且都没有执行结束,而并行是说在单位时间内多个任务同时在执行。并发任务强调在一个时间段内同时执行,而一个时间段由多个单位时间累积而成,所以说并发的多个任务在单位时间内不一定同时在执行。在单CPU的时代多个任务都是并发执行的,这是因为单个CPU同时只能执行一个任务。

2024-09-13 10:45:18 899

原创 JAVA线程基础——InheritableThreadLocal的使用和原理

InheritableThreadLocal类通过重写代码(2)和(3)让本地变量保存到了具体线程的 inheritableThreadLocals变量里面,那么线程在通过InheritableThreadLocal 类实例的 set 或者 get 方法设置变量时,就会创建当前线程的inheritableThreadLocals 变量。

2024-09-12 12:23:39 812

原创 JAVA线程基础——ThreadLocal的使用和原理

如图1-6所示,在每个线程内部都有一个名为threadLocals的成员变量,该变量的类型为 HashMap,其中 key 为我们定义的 ThreadLocal 变量的 this引用,value 则为我们使用set方法设置的值。每个线程的本地变量存放在线程自己的内存变量threadLocals中,如果当前线程一直不消亡,那么这些本地变量会一直存在,所以可能会造成内存溢出,因此使用完毕后要记得调用 ThreadLocal的remove 方法删除对应线程的threadLocals中的本地变量。

2024-09-12 11:32:48 2535

原创 JAVA线程基础——线程的创建和常用方法

如上代码中的 MyThread 类继承了 Thread 类,并重写了run()方法。在 main 函数里面创建了一个 MyThread 的实例,然后调用该实例的start 方法启动了线程。需要注意的是,当创建完 thread 对象后该线程并没有被启动执行,直到调用了start方法后才真正启动了线程。其实调用 start 方法后线程并没有马上执行而是处于就绪状态,这个就绪状态是指该线程已经获取了除 CPU 资源外的其他资源,等待获取 CPU 资源后才会真正处于运行状态。

2024-09-09 17:37:44 744 1

原创 mysql日期相关操作

MICROSECOND 微秒。MINUTE 分钟。

2023-12-04 16:00:15 378

原创 java切割字符串

java切割字符串

2023-04-11 19:39:18 144 1

原创 java字符与日期之间的转换,并计算两个时间差

【代码】java字符与日期之间的转换,并计算两个时间差。

2023-04-10 15:22:30 818 2

原创 mysql常用函数

【代码】mysql常用函数。

2023-04-06 16:21:02 189 1

原创 IDEA快捷键大全

sout 生成输出语句。shift+enter 把光标移动到下一行。ctrl+D 复制出当前行。ctrl+Y 删除当前行。ctrl+alt+L 代码调整格式。psvm 生成主方法。

2023-04-04 15:01:41 128 1

空空如也

空空如也

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

TA关注的人

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