【Java-并发编程】
文章平均质量分 84
【Java-多线程与并发编程】
我一直在流浪
这个作者很懒,什么都没留下…
展开
-
Java 多线程 - 利用线程池并发执行一组 Callable 任务
线程池是一种用于管理和复用线程的机制,它可以在需要时创建线程,并在完成任务后将线程放回池中以供重用。这种机制可以减少线程创建和销毁的开销,提高程序的性能和可伸缩性。在并发编程中,线程池可以用来管理并发任务的执行。通过将任务提交到线程池中,可以让线程池自动分配线程来执行任务,从而实现并发执行。线程池还可以控制并发任务的数量,避免系统资源被过度占用,从而提高系统的稳定性和可靠性。定义了一个名为核心线程数为 5,最大线程数为 20。空闲线程的存活时间为 4 秒。使用作为任务队列,可以存储无限多的任务。原创 2023-08-03 11:30:38 · 659 阅读 · 0 评论 -
Java多线程 - 利用Callable或CompletableFuture实现多线程异步任务执行
对于Calleble来说,Future和FutureTask均可以用来获取任务执行结果,不过Future是个接口,FutureTask是Future的具体实现,而且FutureTask还间接实现了Runnable接口,也就是说FutureTask可以作为Runnable任务提交给线程池。如果异步任务没有执行完成,异步结果获取线程(调用线程)会一直被阻塞,一直阻塞到异步任务执行完成,其异步结果返回给调用线程。(2) RunnableFuture通过继承Future接口,从而保证了可以获取未来的异步执行结果。原创 2023-02-20 17:00:07 · 2557 阅读 · 0 评论 -
Java多线程 - 利用线程池执行Runnable/Callable任务
可以把所有任务放在单个线程中串行执行,也可以将每个任务放在各自的线程中执行。这两种方式都存在一些严格的限制:串行执行的问题在于其糟糕的响应性和吞吐量,而“为每个任务分配一个线程”的问题在于资源管理的复杂性。线程池简化了线程的管理工作,异步执行任务在大多数情况下是通过线程池去提交的,而Runnable接口和Callable接口都可以应用于线程池;虽然Executor是个简单的接口,但它却为异步任务执行框架提供了基础,该框架能支持多种不同类型的任务执行策略。(1) 能够取消异步执行中的任务;原创 2022-10-11 16:47:55 · 1657 阅读 · 0 评论 -
Java多线程 - Java锁有了解吗?Synchronized和ReentrantLock区别?说说如何ReentrantLock如何实现超时锁的等待?
当多个线程并发访问某个Java对象时,无论系统如何调度这些线程,也无论这些线程将如何交替操作,这个对象都能表现出一致的、正确的行为,那么对这个对象的操作是线程安全的。如果这个对象表现出不一致的、错误的行为,那么对这个对象的操作不是线程安全的,发生了线程的安全问题。临界区资源表示一种可以被多个线程使用的公共资源或共享数据,但是每一次只能有一个线程使用它。一旦临界区资源被占用,想使用该资源的其他线程则必须等待。在并发情况下,临界区资源是受保护的对象。...原创 2022-08-03 16:28:12 · 687 阅读 · 0 评论 -
Java多线程 - 共享锁与独占锁
文章目录1. 独占锁2. 共享锁2.1 Semaphore2.2 共享锁使用示例1. 独占锁独占锁也叫排他锁、互斥锁、独享锁,是指锁在同一时刻只能被一个线程所持有。一个线程加锁后,任何其他试图再次加锁的线程都会被阻塞,直到持有锁线程解锁。通俗来说,就是共享资源某一时刻只能有一个线程访问,其余线程阻塞等待。如果是公平地独占锁,在持有锁线程解锁时,如果有一个以上的线程在阻塞等待,那么最先抢锁的线程被唤醒变为就绪状态去执行加锁操作,其他的线程仍然阻塞等待。java中的Synchronized内置锁和Ree原创 2022-03-25 17:42:05 · 3026 阅读 · 0 评论 -
Java多线程 - 可中断锁与不可中断锁
可中断锁是指抢占过程可以被中断的锁,JUC的显式锁(如ReentrantLock)是一个可中断锁。不可中断锁是指抢占过程不可以被中断的锁,如Java的synchronized内置锁就是一个不可中断锁。锁的可中断抢占:在JUC的显式锁Lock接口中,有以下两个方法可以用于可中断抢占:(1)lockInterruptibly()可中断抢占锁抢占过程中会处理Thread.interrupt()中断信号,如果线程被中断,就会终止抢占并抛出InterruptedException异常。(2)tryLock(原创 2022-03-22 17:04:03 · 1974 阅读 · 0 评论 -
Java多线程 - 公平锁与非公平锁
文章目录1. 非公平锁2. 公平锁synchronized内置锁是一种非公平锁,默认情况下ReentrantLock锁也是非公平锁。1. 非公平锁什么是非公平锁呢?非公平锁是指多个线程获取锁的顺序并不一定是其申请锁的顺序,有可能后申请的线程比先申请的线程优先获取锁,抢锁成功的次序不一定体现为FIFO(先进先出)顺序。非公平锁的优点在于吞吐量比公平锁大,它的缺点是有可能会导致线程优先级反转或者线程饥饿现象。使用ReentrantLock锁作为非公平锁的实战用例,具体代码如下:public clas原创 2022-03-22 16:18:32 · 646 阅读 · 0 评论 -
Java多线程 - 悲观锁与乐观锁
文章目录1. 悲观锁存在的问题2. 通过CAS实现乐观锁3. 不可重入的自旋锁4. 可重入的自旋锁问题:1、乐观锁和悲观锁的理解及如何实现,有哪些实现方式?2、什么是乐观锁和悲观锁?3、乐观锁可以重入吗?1. 悲观锁存在的问题独占锁其实就是一种悲观锁,java的synchronized是悲观锁。悲观锁可以确保无论哪个线程持有锁,都能独占式访问临界区。虽然悲观锁的逻辑非常简单,但是存在不少问题。悲观锁总是假设会发生最坏的情况,每次线程读取数据时,也会上锁。这样其他线程在读取数据时就会被阻塞,直到原创 2022-03-21 20:12:24 · 362 阅读 · 0 评论 -
Java多线程 - 显式锁的分类
文章目录1. 可重入锁和不可重入锁2. 悲观锁和乐观锁3. 公平锁和非公平锁4. 可中断锁和不可中断锁5. 共享锁和独占锁显式锁有很多种,从不同的角度来看,显式锁大概有以下几种分类:可重入锁和不可重入锁、悲观锁和乐观锁、公平锁和非公平锁、共享锁和独占锁、可中断锁和不可中断锁。1. 可重入锁和不可重入锁从同一个线程是否可以重复占有同一个锁对象的角度来分,显式锁可以分为可重入锁与不可重入锁。可重入锁也叫作递归锁,指的是一个线程可以多次抢占同一个锁。例如,线程A在进入外层函数抢占了一个Lock显式锁之后,原创 2022-03-21 19:21:53 · 453 阅读 · 0 评论 -
Java多线程 - LockSupport工具类
文章目录1. LockSupport的常用方法2. LockSupport.park()和Thread.sleep()的区别3. LockSupport.park()与Object.wait()的区别LockSupport是JUC提供的一个线程阻塞与唤醒的工具类,该工具类可以让线程在任意位置阻塞和唤醒,其所有的方法都是静态方法。1. LockSupport的常用方法public class LockSupport { // 无限期阻塞线程 public static void park原创 2022-03-11 16:59:55 · 841 阅读 · 0 评论 -
Java多线程 - 基于Lock锁进行“等待-通知”方式的线程间通信
“等待-通知”方式的线程间通信机制,具体来说是指一个线程A调用了同步对象的wait()方法进入等待状态,而另一线程B调用了同步对象的notify()或者notifyAll()方法去唤醒等待线程,当线程A收到线程B的唤醒通知后,就可以重新开始执行了。需要特别注意的是,在通信过程中,线程需要拥有同步对象的监视器,在执行Object对象的wait、notify方法之前,线程必须先通过抢占到内置锁而成为其监视器的Owner。基于Lock显式锁,JUC也为大家提供了一个用于线程间进行“等待-通知”方式通信的接口,原创 2022-03-11 16:11:34 · 357 阅读 · 0 评论 -
Java多线程 - Lock接口实现类:ReentrantLock
ReentrantLock是JUC包提供的显式锁的一个基础实现类,ReentrantLock类实现了Lock接口,它拥有与synchronized相同的并发性和内存语义,但是拥有了限时抢占、可中断抢占等一些高级锁特性。此外,ReentrantLock基于内置的抽象队列同步器(Abstract Queued Synchronized,AQS)实现,在争用激烈的场景下,能表现出表内置锁更佳的性能。ReentrantLock和Synchronize一样都是一个可重入的独占锁,其中两个修饰词的含义为:可重入的含原创 2022-03-11 16:10:06 · 932 阅读 · 0 评论 -
Java多线程 - Lock接口及3个加锁方法的区别
文章目录1. Lock接口2. 使用显式锁的模板代码1. Lock接口与Java内置锁不同,JUC显式锁是一种非常灵活的、使用纯Java语言实现的锁,这种锁的使用非常灵活,可以进行无条件的、可轮询的、定时的、可中断的锁获取和释放操作。由于JUC锁加锁和解锁的方法都是通过Java API显式进行的,因此也叫显式锁。JDK 5版本引入了Lock接口,Lock是Java代码级别的锁。为了与Java对象锁相区分,Lock接口叫作显式锁接口,其对象实例叫作显式锁对象。Lock接口位于java.util.conc原创 2022-03-11 16:00:44 · 1843 阅读 · 0 评论 -
Java多线程 - ThreadLocal造成内存泄漏的原因和解决方案
仅有弱引用(Weak Reference)指向的对象只能生存到下一次垃圾回收之前。换句话说,当GC发生时,无论内存够不够,仅有弱引用所指向的对象都会被回收。而拥有强引用指向的对象则不会被直接回收。原创 2022-03-10 11:26:28 · 2987 阅读 · 0 评论 -
Java多线程 - ThreadLocal源码解析
文章目录1. ThreadLocal内部结构2. ThreadLocal源码分析3. ThreadLocalMap源码分析1. ThreadLocal内部结构在早期的JDK版本中,ThreadLocal的内部结构是一个Map,其中每一个线程实例作为Key,线程在“线程本地变量”中绑定的值为Value,每一个ThreadLocal实例拥有一个Map实例。在JDK 8版本中,每一个Thread线程内部都有一个ThreadLocalMap,其中ThreadLocal实例为Key,本地数据为Value。如果原创 2022-03-10 10:50:02 · 347 阅读 · 0 评论 -
Java多线程 - ThreadLocal的作用? 有哪些使用场景?
文章目录1. ThreadLocal是什么?2. ThreadLocal基本作用?3. ThreadLocal的应用场景?问题:1、ThreadLocal 是什么?有哪些使用场景?2、ThreadLocal的设计理念与作用?3、什么叫线程局部变量?1. ThreadLocal是什么?在Java的多线程并发执行过程中,为了保证多个线程对变量的安全访问,可以将变量放到ThreadLocal类型的对象中,使变量在每个线程中都有独立值,不会出现一个线程读取变量时被另一个线程修改的现象。Thread原创 2022-03-09 17:09:15 · 2919 阅读 · 0 评论 -
Java多线程 - 如何确定线程池的线程数?
问题:1、高并发、任务执行时间短的业务怎样使用线程池?2、并发不高、任务执行时间长的业务怎样使用线程池?3、并发高、业务执行时间长的业务怎样使用线程池?使用标准构造器ThreadPoolExecutor创建线程池时,会涉及线程数的配置,而线程数的配置与异步任务类型是分不开的。这里将线程池的异步任务大致分为以下三类:(1)IO密集型任务此类任务主要是执行IO操作。由于执行IO操作的时间较长,导致CPU的利用率不高,这类任务CPU常处于空闲状态。Netty的IO读写操作为此类任务的典型例子。由原创 2022-03-09 14:46:49 · 1855 阅读 · 0 评论 -
Java多线程 - Executors和ThreaPoolExecutor创建线程池的区别?
文章目录1. 使用Executors创建“固定数量的线程池”的潜在问题2. 使用Executors创建“单线程化线程池”的潜在问题3. 使用Executors创建“可缓存线程池”的潜在问题4. 使用Executors创建“可调度线程池”的潜在问题5. 总结在很多公司的编程规范中,非常明确地禁止使用Executors快捷创建线程池,为什么呢?这里从源码讲起,介绍使用Executors工厂方法快捷创建线程池将会面临的潜在问题。1. 使用Executors创建“固定数量的线程池”的潜在问题public st原创 2022-03-09 11:20:52 · 399 阅读 · 0 评论 -
Java多线程 - 线程池都有哪些状态?
线程池总共存在5种状态,定义在ThreadPoolExecutor类中,具体代码如下:public class ThreadPoolExecutor extends AbstractExecutorService { private static final int RUNNING = -1 << COUNT_BITS; private static final int SHUTDOWN = 0 << COUNT_BITS; private st原创 2022-03-09 10:55:52 · 1269 阅读 · 0 评论 -
Java多线程 - ThreadPoolExecutor构造函数的参数?
文章目录1. 核心和最大线程数量2. keepAliveTime3. ThreadFactory4. 任务阻塞队列5. 线程池的拒绝策略1、ThreadPoolExecutor构造函数重要参数分析?2、ThreadPoolExecutor饱和策略?3、如果你提交任务时,线程池队列已满,这时会发生什么?使用ThreadPoolExecutor的构造函数创建线程池:/** * 使用标准构造器构造一个普通的线程池 * * @param corePoolSize 核心线程数,即使线程空闲,也不原创 2022-03-08 16:22:08 · 562 阅读 · 0 评论 -
Java多线程 - 线程池的任务调度流程?
问题:1、 线程池的启动策略?2、线程池的任务调度流程?3、线程池的工作原理?/** * 使用标准构造器构造一个普通的线程池 * * @param corePoolSize 核心线程数,即使线程空闲,也不会回收 * @param maximumPoolSize 线程数的上限(最大线程数) * @param keepAliveTime 线程最大空闲时间(线程的生存时间) * @param unit 时间单位 * @param workQueue 任务的排队队列 * @para原创 2022-03-08 15:03:09 · 1079 阅读 · 0 评论 -
Java多线程 - 常用的几种线程池及其工作原理?
文章目录1. newSingleThreadExecutor() 创建单线程化线程池2. newFixedThreadPool() 创建固定数量的线程池3. newCachedThreadPool() 创建可缓存线程池4. newScheduledThreadPool() 创建可调度线程池5. 如何使用线程池?问题:1、常用的几种线程池并讲讲其中的工作原理?2、高并发、任务执行时间短的业务怎样使用线程池? 并发不高、任务执行时间长的业务怎样使用线程池?并发高、业务执行时间长的业务怎样使用线程池?原创 2022-03-08 14:48:32 · 317 阅读 · 0 评论 -
Java多线程 - 线程池中submit()和execute()方法有什么区别?
问题:线程池中submit() 和execute() 方法有什么区别?向线程池提交任务的两种方式:方式一:调用execute()方法,例如:// Executor接口中的方法public interface Executor { void execute(Runnable command);}方式二:调用submit()方法,例如:// ExecutorService接口中的方法public interface ExecutorService extends Executor原创 2022-03-08 11:49:46 · 3175 阅读 · 0 评论 -
Java多线程 - 什么是线程池?优点?线程池有哪几种创建方式?
文章目录1. 线程池有什么优点?2. 什么是线程池?3. Executors的4种快捷创建线程池的方法3.1 newSingleThreadExecutor创建:单线程化线程池3.2 newFixedThreadPool创建:固定数量的线程池3.3 newCachedThreadPool创建:可缓存线程池3.4 newScheduledThreadPool创建:可调度线程池4. 线程池的标准创建方式问题思考:1、什么是线程池?2、线程池有什么优点?3、线程池有哪几种创建方式?1. 线程池有什么原创 2022-03-07 20:28:46 · 527 阅读 · 0 评论 -
Java多线程 - CAS会有什么问题?
文章目录1. 什么是ABA问题?2. 使用AtomicStampedReference解决ABA问题3. 使用AtomicMarkableReference解决ABA问题由于CAS原子操作性能高,因此其在JUC包中被广泛应用,只不过如果使用得不合理,CAS原子操作就会存在ABA问题。1. 什么是ABA问题?比如一个线程A从内存位置M中取出V1,另一个线程B也取出V1。现在假设线程B进行了一些操作之后将M位置的数据V1变成了V2,然后又在一些操作之后将V2变成了V1。之后,线程A进行CAS操作,但是线程原创 2022-03-07 16:01:08 · 595 阅读 · 0 评论 -
Java多线程 - AtomicInteger线程安全原理
文章目录问题1:AtomicInteger线程安全原理问题2:AtomicIntegerArray中的数组为什么没有使用volatile修饰?问题3:说一下Atomic的原理?问题1:AtomicInteger线程安全原理基础原子类(以AtomicInteger为例)主要通过CAS自旋+volatile的方案实现,既保障了变量操作的线程安全性,又避免了synchronized重量级锁的高开销,使得Java程序的执行效率大为提升。CAS用于保障变量操作的原子性,volatile关键字用于保障变量的可见性,原创 2022-03-04 15:31:30 · 1455 阅读 · 0 评论 -
Java多线程 - 什么是原子操作? JUC并发包中的原子类有哪些?
文章目录1. 什么是原子操作?2. JUC并发包中的原子类有哪些?3. 基础原子类AtomicInteger4. 数组原子类AtomicIntegerArray问题:什么是原子操作? JUC并发包中的原子类有哪些?什么是 CAS 算法?在多线程中有哪些应用。在多线程并发执行时,诸如“++”或“–”类的运算不具备原子性,不是线程安全的操作。通常情况下,大家会使用synchronized将这些线程不安全的操作变成同步操作,但是这样会降低并发程序的性能。所以,JDK为这些类型不安全的操作提供了一些原子类,原创 2022-03-04 11:52:14 · 499 阅读 · 0 评论 -
Java多线程 - 什么是CAS?
问题:什么是CAS?由于JVM的Synchronized重量级锁涉及操作系统(如Linux)内核态下互斥锁的使用,因此其线程阻塞和唤醒都涉及进程在用户态到内核态的频繁切换,导致重量级锁开销大、性能低。而JVM的Synchronized轻量级锁使用CAS(Compare And Swap,比较并交换)进行自旋抢锁,CAS是CPU指令级的原子操作,并处于用户态下,所以JVM轻量级锁的开销较小。JDK 5所增加的JUC(java.util.concurrent)并发包对操作系统的底层CAS原子操作进行了封装,原创 2022-03-04 10:05:04 · 471 阅读 · 0 评论 -
Java多线程 - volatile不具备原子性
问题:volatile 能使得一个非原子操作变成原子操作吗?volatile能保证数据的可见性,但volatile不能完全保证数据的原子性,不能防止指令交错,对于volatile类型的变量进行复合操作,其仍存在线程不安全的问题。对于关键字volatile修饰的内存可见变量而言,具有两个重要的语义:(1)使用volatile修饰的变量在变量值发生改变时,会立刻同步到主存,并使其他线程的变量副本失效。(2)禁止指令重排序:用volatile修饰的变量在硬件层面上会通过在指令前后加入内存屏障来实现,编译原创 2022-03-03 17:25:50 · 701 阅读 · 0 评论 -
Java多线程 - 什么是Java内存模型?
文章目录1. 什么是Java内存模型2. JMM和JVM物理内存的区别3. JMM的8个操作4. JMM如何解决有序性问题5. volatile关键字中的内存屏障问题:1.什么是Java内存模型?2. volatile的作用?1. 什么是Java内存模型java内存模型(java memory model,JMM)定义了一组规则或规范,该规范定义了一个线程对共享变量写入时,如何确保对另一个线程是可见的。实际上,JMM提供了合理的禁用缓存以及禁止重排序的方法,所以其核心的价值在于解决可见性和有序性。原创 2022-03-03 16:53:11 · 233 阅读 · 0 评论 -
Java多线程 - 可见性和有序性原理
文章目录1. 缓存一致性协议解决可见性问题1. CPU物理缓存结构2. 内存的可见性问题3. 总线锁和缓存锁2. 内存屏障解决可见性和有序性问题3. volatile的底层原理问题:violatile 关键字的作用?1. 缓存一致性协议解决可见性问题1. CPU物理缓存结构由于CPU的运算速度比主存的存取速度快很多,为了提高处理速度,现代CPU不直接和主存进行通信,而是在CPU和主存之间设计了多层的Cache(高速缓存),越靠近CPU的高速缓存越快,容量也越小。按照数据读取顺序和与CPU内核结合的原创 2022-03-02 17:52:04 · 867 阅读 · 0 评论 -
Java多线程 - 什么是原子性、可见性、有序性?
文章目录1. 原子性问题2. 可见性问题3. 有序性问题问题:1.什么是原子性、可见性、有序性?1. 原子性问题原子性、可见性、有序性是并发编程所面临的三大问题。所谓原子操作,就是“不可中断的一个或一系列操作”,是指不会被线程调度机制打断的操作。这种操作一旦开始,就一直运行到结束,中间不会有任何线程的切换。例如对于 i++ 而言,实际会产生如下的 JVM 字节码指令:getstatic i // 获取静态变量i的值(内存取值)iconst_1 // 准备常量1iadd原创 2022-03-01 19:46:29 · 491 阅读 · 0 评论 -
Java多线程 - 生产者消费者模式
文章目录1. 生产者消费者模型2. 实现生产者消费者模型3. 生产者消费者模型的作用是什么?问题:1.什么是阻塞队列?如何使用阻塞队列来实现生产者-消费者模型?2. 生产者消费者模型的作用是什么?1. 生产者消费者模型在生产者-消费者模式中,通常有两类线程,即生产者线程(若干个)和消费者线程(若干个)。生产者线程向消息队列加入数据,消费者线程则从消息队列消耗数据。生产者和消费者、消息队列之间的关系结构图如图:(1) 消息队列可以用来平衡生产和消费的线程资源;(2) 生产者仅负责产生结果数据,原创 2022-03-01 15:37:51 · 322 阅读 · 0 评论 -
Java多线程 - 如何正确的使用wait-notify方法?
文章目录1. sleep(long n) 和 wait(long n) 的区别2. 正确使用wait-notify方法 [while(条件)+wait]2.1 问题12.2 问题22.3 问题32.4 问题42.5 最终结果问题:sleep() 和 wait() 有什么区别?1. sleep(long n) 和 wait(long n) 的区别(1) sleep 是 Thread 方法,而 wait 是 Object 的方法 ;(2) sleep 不需要强制和 synchronized 配合使用原创 2022-03-01 11:47:42 · 263 阅读 · 0 评论 -
Java多线程 - 线程通信之wait-notify通信方式
文章目录1. 线程通信的定义2. 为什么需要wait-notify?3. wait方法和notify方法4. wait方法和notify方法的原理5. wait方法和notify方法示例问题:线程 wait()方法使用有什么前提?多线程之间如何进行通信?Java 中 notify 和 notifyAll 有什么区别?为什么 wait/notify/notifyAll 这些方法不在 thread 类里面?为什么 wait 和 notify 方法要在同步块中调用?notify()和 notify原创 2022-03-01 10:05:01 · 407 阅读 · 0 评论 -
Java多线程 - synchronized锁升级的原理
synchronized的执行过程,大致如下:(1) 线程抢锁时,JVM首先检测内置锁对象Mark Word中的biased_lock(偏向锁标识)是否设置成1,lock(锁标志位)是否为01,如果都满足,确认内置锁对象为可偏向状态。(2) 在内置锁对象确认为可偏向状态之后,JVM检查Mark Word中的线程ID是否为抢锁线程ID,如果是,就表示抢锁线程处于偏向锁状态,抢锁线程快速获得锁,开始执行临界区代码。(3) 如果Mark Word中的线程ID并未指向抢锁线程,就通过CAS操作竞争锁。如果竞争原创 2022-02-28 17:35:10 · 266 阅读 · 0 评论 -
Java多线程 - synchronized重量级锁的核心原理
在JVM中,每个对象都关联一个监视器,这里的对象包含Object实例和Class实例。监视器是一个同步工具,相当于一个许可证,拿到许可证的线程即可进入临界区进行操作,没有拿到则需要阻塞等待。重量级锁通过监视器的方式保障了任何时间只允许一个线程通过受到监视器保护的临界区代码。1. monitor原理jvm中每个对象都会有一个监视器Monitor,监视器和对象一起创建、销毁。监视器相当于一个用来监视这些线程进入的特殊房间,其义务是保证(同一时间)只有一个线程可以访问被保护的临界区代码块。每一个锁都对应一个原创 2022-02-28 17:13:17 · 1322 阅读 · 0 评论 -
Java多线程 - synchronized轻量级锁的核心原理
文章目录1. 轻量级锁的原理2. 轻量级锁的分类3. 轻量级锁的膨胀面试题:什么是自旋锁?说一下 synchronized 底层实现原理?多线程中 synchronized 锁升级的原理是什么?1. 轻量级锁的原理引入轻量级锁的主要目的是在多线程竞争不激烈的情况下,通过CAS机制竞争锁减少重量级锁产生的性能损耗。重量级锁使用了操作系统底层的互斥锁(Mutex Lock),会导致线程在用户态和核心态之间频繁切换,从而带来较大的性能损耗。轻量级锁的使用场景:如果一个对象虽然有多线程要加锁,但加原创 2022-02-28 16:20:11 · 434 阅读 · 0 评论 -
Java多线程 - synchronized偏向锁的核心原理
1. 偏向锁的核心原理轻量级锁在没有竞争时(就自己这个线程),每次重入仍然需要执行 CAS 操作。 Java 6 中引入了偏向锁来做进一步优化:只有第一次使用 CAS 将线程 ID 设置到对象的 Mark Word 头,之后发现 这个线程 ID 是自己的就表示没有竞争,不用重新 CAS。以后只要不发生竞争,这个对象就归该线程所有。public class Main { static final Object obj = new Object(); public static void m原创 2022-02-28 11:28:00 · 647 阅读 · 0 评论 -
Java多线程 - Java对象结构与对象锁的升级
文章目录1. Java对象结构2. Mark Word的结构信息3. 无锁、偏向锁、轻量级锁和重量级锁1. Java对象结构Java对象结构包括三部分:对象头、对象体和填充字节,如图所示:对象头又包括三个字段:第一个字段叫作Mark Word(标记字),用于存储自身运行时的数据,例如GC标志位、哈希码、锁状态等信息。第二个字段叫作Class Pointer(类对象指针),用于存放方法区Class对象的地址,虚拟机通过这个指针来确定这个对象是哪个类的实例。第三个字段叫作Array L原创 2022-02-25 12:31:33 · 542 阅读 · 0 评论