juc
文章平均质量分 62
多线程&并发
Shen_Li_Java_ing
加电!加电!!加电!!!
展开
-
带你了解ReentrantLock整体流程(底层原理-醒目版)
进入队列后,线程会进行自旋等待,不断检查锁的状态,直到锁变得可用或者线程被中断。这个方法会尝试在给定的超时时间内获取锁,如果超时时间到达仍未获取到锁,或者线程在等待过程中被中断,那么它会返回。等尝试获取锁的方法。这些方法在未能立即获取锁时不会阻塞线程,而是立即返回,因此在使用这些方法时,解锁的操作需要由程序员显式控制。这种非阻塞式的尝试获取锁的方式使得线程在未能获取到锁时可以立即进行其他操作,而不是被阻塞等待。:对于某些高并发场景,非阻塞式的锁获取机制可以减少线程上下文切换的开销,从而提高程序的性能。原创 2024-04-21 11:25:29 · 783 阅读 · 1 评论 -
Synchronized和 ReentrantLock区别
在锁的获取与释放、公平性、灵活性、锁的粒度、响应中断以及底层实现等方面存在显著的区别。是一个关键字,它在进入同步代码块或方法时自动获取锁,并在退出时自动释放锁。这种隐式的锁获取和释放简化了同步代码的编写,但可能也降低了灵活性。可以是公平锁,它提供了构造函数来设置锁的公平性。是不可中断的,一旦线程进入同步代码块或方法,它将一直等待直到获取锁,即使线程被中断。是一个类,它提供了显式的锁获取和释放方法。是非公平锁,它不能保证等待时间最长的线程最先获取锁。是API层面的锁,它的实现完全基于Java代码。原创 2024-04-21 10:20:06 · 396 阅读 · 1 评论 -
线程的6种状态
TIMED_WAITING(超时等待)状态相当于在等待状态的基础上增加了超时限制,比如通过sleep(long millis)方法或 wait (long millis)方法可以将线程置于TIMED_WAITING状态。当线程进入synchronized方法/块或者调用wait后(被notify )重新进入synchronized方法/块,但是锁被其它线程占有,这个时候线程就会进入BLOCKED(阻塞)状态。当线程执行wait()方法之后,线程进入WAITING(等待)状态。原创 2024-04-20 21:36:55 · 304 阅读 · 0 评论 -
Semaphore、CountDownLatch、CyclicBarrier的区别
与CountDownLatch不同的是,CyclicBarrier的屏障可以在最后一次使用之后重置,因此它可以被循环使用。当所有线程都到达屏障点时,可以选择执行一个特定的操作,然后再继续执行。Semaphore关注资源的访问控制,CountDownLatch关注一组线程中某些操作的先后顺序,而CyclicBarrier则关注一组线程之间的相互等待和同步。Semaphore、CountDownLatch和CyclicBarrier在Java中都是用于控制多线程执行的工具类,但它们各自有不同的使用场景和特性。原创 2024-04-20 15:12:57 · 502 阅读 · 0 评论 -
AQS知识补充(一)
如果队列不为空的话,首先会让新节点prev指针指向当前队列的队尾,再将tail指针指向新结点,最后将新节点的前驱结点的next指针指向新结点。如果当前队列为空的话,虚拟化出一个新的 Node 头节点,这时队列中只有一个元素,为了保证 AQS 队列结构的完整性,会将尾节点指向头节点。在AQS中,队列中线程的阻塞唤醒都是通过LockSupport实现的。同步阻塞状态,类似调用了Object.wait()取消状态,标志该线程不再参与锁的争抢。park():阻塞当前调用线程。共享模式,同步状态可传播状态。原创 2024-04-18 22:32:29 · 229 阅读 · 1 评论 -
如何介绍AQS
AQS是多线程同步器,它是JUC包中多个组件的底层实现,比如说像lock、countdownlatch、Semaphore都用到了AQS, 从本质上来说AQS提供了两种锁的机制,分别是排他锁和共享锁。原创 2024-04-18 22:00:54 · 452 阅读 · 1 评论 -
聊聊synchronized锁优化升级
在代码进入同步块的时候,如果同步对象锁状态为无锁状态(锁标志位为“01”状态,是否为偏向锁为“0”),虚拟机首先将在当前线程的栈帧中建立一个名为锁记录(Lock Record)的空间,用于存储锁对象目前的Mark Word的拷贝,然后拷贝对象头中的Mark Word复制到锁记录中。如果轻量级锁的更新操作失败了,虚拟机首先会检查对象的Mark Word是否指向当前线程的栈帧,如果是就说明当前线程已经拥有了这个对象的锁,那就可以直接进入同步块继续执行,否则说明多个线程竞争锁。原创 2024-04-17 21:48:12 · 860 阅读 · 1 评论 -
为什么阿里巴巴的开发手册中禁止使用Executors创建线程池
在上面的例子中,我们创建了一个固定大小为10的线程池,然后向它提交了几乎无穷多的任务。由于每个任务都执行了很长时间,并且线程池的大小是固定的,newFixedThreadPool采用的是无界队列,而新的任务会不断提交,这可能导致内存耗尽或任务被拒绝。在这个例子中,我们明确指定了线程池的核心线程数、最大线程数、队列大小等参数,以及拒绝策略。,如果任务数量过多且执行速度较慢,可能会创建大量的线程,从而导致 OOM。来创建线程池,并明确指定线程池的大小、队列大小以及拒绝策略等参数。:使用的无界的延迟阻塞队列。原创 2024-04-16 13:17:58 · 526 阅读 · 0 评论 -
线程池的工作流程及线程池参数
(任务队列): 新任务来的时候会先判断当前运行的线程数量是否达到核心线程数,如果达到的话,新任务就会被存放在队列中。:如果线程池无法接受新任务,则由主线程(提交任务的线程)自己执行这个任务。当池中工作线程数小于corePoolSize(核心线程数) 的时候,每次来任务的时候都会创建一个新的工作线程。(最大线程数): 任务队列中存放的任务达到队列容量的时候,当前可以同时运行的线程数量变为最大线程数。的时候,如果这时没有新的任务提交,核心线程外的线程不会立即销毁,而是会等待,直到等待的时间超过了。原创 2024-04-16 09:22:55 · 414 阅读 · 0 评论 -
为什么wait()方法不定义在Thread中?
都拥有对象锁,既然要释放当前线程占有的对象锁并让其进入 WAITING 状态,自然是要操作对应的对象(这允许我们实现一个简单的生产者-消费者模型,其中一个线程增加计数,另一个线程减少计数。是让获得对象锁的线程实现等待,会自动释放当前线程占有的对象锁。是让当前线程暂停执行,不涉及到对象类,也不需要获得对象锁。以下是一个简单的例子,展示了如何在Java中使用。达到某个值时(在这个例子中是5或0),调用。的线程将等待,直到其他线程调用。在这个例子中,我们有一个。原创 2024-04-15 10:02:53 · 312 阅读 · 0 评论