首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

每日五分钟,玩转JVM(三):线程独占

上节课我们说到多线程的实现是基于时分复用来实现的,为了每个线程的运行的互不干扰和有序性,程序计数器必须保证在切换时能够回到正确的位置,所以它必须也必然是线程独占区的一份子。...关键字: 行号指示器 执行中字节码指令地址 没有OOM Native方法不归他管 线程独享 栈 虚拟机栈 虚拟机栈是Java方法运行时的内存模型,包括了局部变量表,操作数栈,动态连接,方法返回地址以及一些附加信息...public native String intern(); 异常 本地方法栈和虚拟机栈同为栈结构之中,他们会面对两种异常,当线程请求的栈深度大于虚拟机所允许的深度时,将抛出StackOverflowError

41130

AQS之独占

Node 有独占和共享两种模式,通过Node的内部属性nextWaiter表示,独占为EXCLUSIVE,独占为SHARED 状态state,被volatile关键字修饰,独占模式下,等于0代表可以获取锁...,我们需要根据需求重写tryAcquire、tryRelease等模板方法就可以了,基于这个特性,你可以实现所谓的公平锁和非公平锁等 本文主要基于ReentrantLock来分析AQS的独占模式 ReentrantLock...LockSupport.park(this); // 判断当前线程是否发生中断 return Thread.interrupted(); } 阻塞当前线程 返回当前线程是否发生中断...,如果不是,说明当前线程没有获得锁,因此不能释放,此时抛出异常 如果当前线程是持有锁的线程, 如果 (sate-1) == 0,说明没有重入锁了,此时需要对 上一个节点对应的线程 进行解除阻塞操作 如果...,此时该线程都没有获得锁,也就没有发生阻塞,自然也不需要对该线程解除阻塞 根据上一步获取的节点获取线程,然后通过 LockSupport#unpark 方法对该线程解除阻塞 ReentrantLock.NonfairSync

56010
您找到你想要的搜索结果了吗?
是的
没有找到

动画:深度解析JVM运行时数据区 之 线程独占

Oracle在发布新的JAVA版本时,可能会对JVM做一定的优化和改进,例如在JDK8的版本中,方法区被移除,取而代之的是metaspace(元数据空间) 从上图我们可以看出,内存区域主要分为两部分: 线程独占区...包括:程序计数器,虚拟机栈,本地方法栈 线程共享区 包括: 方法区,堆 我们先从线程独占区开始讲起 [euuptnm69h.png] 程序计数器 程序计数器:一块较小的内存空间,记录着当前线程所执行的字节码的行号指示器...作用 JVM的多线程是通过CPU时间片轮转(即线程轮流切换并分配处理器执行时间)算法来实现的。也就是说,某个线程在执行过程中可能会因为时间片耗尽而被挂起,而另一个线程获取到时间片开始执行。...因此,程序计数器是具备线程隔离的特性,也就是说,每个线程工作时都有属于自己的独立计数器。不同线程之间的程序计数器互不影响,独立存储。...由于篇幅问题,今天我们就先讲线程独占区的几个知识点,下节我会同样用动图的方式来讲解方法区和java堆是如何创建对象实例的。大家敬请期待。

1.1K51

Java并发:AbstractQueuedSynchronizer详解(独占模式)

acquireInterruptibly(int):独占模式的获取,可中断 tryAcquireNanos(int, long):独占模式的获取,可中断,并且有超时时间。...release(int):独占模式的释放。 acquireShared(int):共享模式的获取,忽略中断。...(参考基础属性中的图) nextWaiter可以分为3种情况:1)共享模式的节点,值固定为源码中的常量SHARED;2)独占模式的普通节点:值固定为源码中的常量EXCLUSIVE,也就是null;3)独占模式的条件队列节点...,在AQS中该方法是没有实现的,子类必须实现,主要用于以独占模式尝试acquire。...例如在ReentrantLock中的实现逻辑是:先获取当前的同步状态,再使用CAS尝试将同步状态修改成期望值,如果修改成功将拥有独占访问权的线程设置为当前线程

53240

AbstractQueuedSynchronizer 原理分析 - 独占共享模式

(int arg) 共享式获取同步状态 boolean tryReleaseShared(int arg) 共享式私房同步状态 boolean isHeldExclusively() 检测当前线程是否获取独占锁...如下: 方法 说明 void acquire(int arg) 独占式获取同步状态,该方法将会调用 tryAcquire 尝试获取同步状态。获取成功则返回,获取失败,线程进入同步队列等待。...= null) // 唤醒 node 的后继节点线程 LockSupport.unpark(s.thread); } 到这里,独占式获取同步状态的分析就讲完了。...这里对独占式获取同步状态的大致流程做个总结,如下: 调用 tryAcquire 方法尝试获取同步状态 获取成功,直接返回 获取失败,将线程封装到节点中,并将节点入队 入队节点在 acquireQueued...相对于独占式获取同步状态,共享式的情况更为复杂。独占模式下,只有一个节点线程可以成功获取同步状态,也只有获取已同步状态节点线程才可以释放同步状态。

3.5K155

ReentrantLock可重入独占锁详解

内部维护了一个Sync,它继承AQS,实现AQS提供的独占式的获取与释放同步资源的方法,提供了可重入的具体实现。...独占锁表示:同时只能有一个线程可以获取该锁,其他获取该锁的线程会被阻塞而被放入该所的AQS阻塞队列里面。...这部分可以查看:Java并发包源码学习系列:AQS共享式与独占式获取与释放资源的区别 构造方法 Sync直接继承自AQS,NonfairSync和FairSync继承了Sync,实现了获取锁的公平与非公平策略...BlockingQueue { final Object[] items; // 缓冲数组 final ReentrantLock lock = new ReentrantLock(); // 非公平独占锁...总结 API层面的独占锁:ReentrantLock是底层使用AQS实现的可重入的独占锁,区别于synchronized原生语法层面实现锁语义,ReetrantLock通过lock()和unlock()

20310

AQS独占锁和重入锁详解

独占模式则代表着在同一时刻只运行一个线程对锁资源进行操作,如ReentranLock等组件的实现都是基于AQS的独占模式实现。...但是不管是独占模式还是共享模式的实现类,都是建立在AQS的基础上实现,其内部都维持着一个队列,当试图获取锁的线程数量超过当前模式限制时则会将线程封装成一个Node节点加入队列进行等待。...,所以需要用CAS操作保证原子性 if (compareAndSetState(0, 1)) // 成功则将独占线程设置为当前线程...),成功则将独占线程设置为当前获取同步状态的线程,最后返回ture。...二、判断当前线程current是否为独占线程OwnerThread,如果是则代表着当前线程已经获取过锁资源还未释放,属于锁重入,那么对state进行自增1,返回true。

1.4K00

Java的独占锁和共享锁

共享锁 在Java中,共享锁(Shared Lock)是一种允许多个线程同时读取资源,但在写入资源时只允许一个线程独占的锁。...在公平模式下,等待时间最长的线程将优先获得锁;而在非公平模式下,锁的分配不保证任何特定的顺序,新到来的线程可能立即获得锁。 要注意的是,尽管读锁是共享的,但写锁是独占的,并且写锁具有更高的优先级。...独占锁 在Java中,独占锁(Exclusive Lock)是一种同步机制,它确保在给定时间内只有一个线程能够访问特定的资源或代码块。...当一个线程持有独占锁时,其他试图获取同一锁的线程将会被阻塞,直到持有锁的线程释放该锁。...然而,独占锁可能会降低并发性,因为它阻止了多个线程同时访问被保护的资源。因此,在设计并发系统时,需要仔细权衡独占锁的使用。 所以关于这四种锁,你了解了么?

11910

JAVA面试备战(十三)--独占锁的释放

如果线程从这里唤醒了,它将接着往下执行。...注意,这里有两个线程: 一个是我们这篇讲的线程,它正在释放锁,并调用了LockSupport.unpark(s.thread) 唤醒了另外一个线程; 而这个另外一个线程,就是我们上一节讲的因为抢锁失败而被阻塞在...绕了这么一大圈,到最后还是中断了当前线程,到底是在干嘛呢? 其实这一切的原因都在于: 我们并不知道线程被唤醒的原因。...,因此我们通过Thread.interrupted()方法检查了当前线程的中断标志,并将它记录下来,在我们最后返回acquire方法后,如果发现当前线程曾经被中断过,那我们就把当前线程再中断一次。...注意,中断对线程来说只是一个建议,一个线程被中断只是其中断状态被设为true, 线程可以选择忽略这个中断,中断一个线程并不会影响线程的执行。 线程中断是一个很重要的概念,这个我们以后有机会再细讲。

47110

可重入的独占锁——ReentrantLock源码分析

当一个线程第一次获取该锁时,会尝试使用CAS设置state的值为1, 如果CAS成功则当前线程获取了该锁,然后记录该锁的持有者为当前线程。...(); //独占锁 private volatile ReentrantLock lock=new ReentrantLock(); //添加元素 public void...如图,假如线程Thread-1,Thread-2,Thread-3同时尝试获取独占锁ReentrantLock,加上Thread-1获取到了?...小结: 本章介绍了ReentrantLock的实现原理,ReentrantLock的底层使用AQS实现的可重入独占锁。在这里AQS状态值为0表示当前?空闲,为大于1的值则说明该?已经被占用了。...内部有公平与非公平实现,默认情况下是非公平的实现,另外,由于该锁的独占锁,所以某一时刻只有一个线程可以获取到该?。 本文参考书籍 Java并发编程之美

55130

JAVA面试备战(十五)--AQS独占锁获取

本篇我们将以ReentrantLock的公平锁为例来详细看看使用AQS获取独占锁的流程。 本文中的源码基于JDK1.8 。...你可以把state变量当做是当前持有该锁的线程数量。 由于本篇我们分析的是独占锁,同一时刻,锁只能被一个线程所持有。...,在独占锁模式下,我们只需要关注CANCELLED SIGNAL两种状态即可。...所代表的线程 waitStatus:表示节点所处的等待状态,独占锁模式下只需关注三种状态:SIGNAL CANCELLED 初始态(0) prev next:节点的前驱和后继 nextWaiter:进作为标记...,值永远为null,表示当前处于独占锁模式 CAS操作 前面我们提到过,CAS操作大对数是用来改变状态的,在AQS中也不例外。

46110

Oculus的VR统治之路:独占+砸钱

答案是投资独占游戏、降低PC标准、培养一个庞大的游戏生态系统以及依靠Facebook强大的财力支撑。 ? Oculus在上周的第三届年度开发者大会上谈及了自己的规划构想,这次的规模也是前所未有的。...在今年上半年,Oculus更新了DRM来阻止HTC Vive的用户使用Oculus的独占游戏。但由于受到民众的普遍抗议和抵制,Oculus最终停止了这种限制。...尽管一直遭到反对,但Oculus并没有放弃独占游戏的开发。 ? Oculus的内容部门负责人Jason Rubin表示;“有一些玩家通过诸如Revive这样的工具来避免Rift的DRM头显检测。”...但由于Rift的独占游戏专门针对Oculus硬件进行了优化,所以用户只能在Oculus上获得最佳的游戏体验。...Oculus会继续独占内容,“每个人都在做独占游戏”Rubin补充道,如果他们不这样做会使Oculus处于劣势。 独占与否,似乎独占让Oculus在竞争中占据上风。

57750

并发锁(二):共享锁和独占

LOCK_EX - 独占锁定(写入的程序)。防止其他进程访问该文件。LOCK_UN - 释放一个共享锁定或独占锁定LOCK_NB - 锁定的情况下避免阻塞其他进程。 block 可选。...LOCK_EX - 独占锁定(写入的程序)。防止其他进程访问该文件。 LOCK_UN - 释放一个共享锁定或独占锁定 LOCK_NB - 锁定的情况下避免阻塞其他进程。 block可选。...首先,我们要分清楚,锁有2种,共享锁,以及独占锁 共享锁 共享锁用于某个文件不会被写,或者不会被更新(也就是只读)的情况,加了共享锁的文件,只能再加共享锁,而不能加独占锁 例如: $file = fopen...同理,如果是先加了独占锁,则共享锁会被阻塞,不做详细说明 注意事项 共享锁加上之后,虽然不能再加上独占锁进行独占写入,但是还是会被未加锁的进程影响,所以注意,当你确定某个文件是只读,或者说读取的时候不被写入影响时...独占独占锁用于数据可能会被修改的文件,当一个进程加上独占锁之后,其他进程将不能增加独占锁和共享锁(将会阻塞) 测试代码: <?

1.5K21

深入理解独占锁ReentrantLock类锁

ReentrantLock介绍 【1】ReentrantLock是一种基于AQS框架的应用实现,是JDK中的一种线程并发访问的同步手段,它的功能类似于synchronized是一种互斥锁,可以保证线程安全...这就涉及到线程的概念了。     (1)因为park()与unpark()操作涉及到了线程的上下文切换,同时又涉及到了时间片轮转机制。     ...(2)线程上下文切换,需要将旧的线程资源保存回内存【保存执行到了哪一步,需要什么东西】,将新的线程的资源加载入CPU,让新线程具备执行的资源并开始执行。...,所以t1线程其实是先进入队列里面,然后在main线程里面将t1设置为了中断。...调用Condition.await() 方法使线程等待,其他线程调用Condition.signal() 或 Condition.signalAll() 方法唤醒等待的线程

33140
领券