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

总结(三) 操作系统

线程同步 呃。 死锁 两个进程竞争资源,每个进程都拿了一部分又不释放,就会出现死锁问题。 死锁四个条件 互斥条件:多个线程不能用同一份资源。...自旋:没获取的时候,进程会忙等待(自旋),一直占用CPU。 所以如果能确定的时间很短,则应该使用互斥,不是自旋。...读和写和其优先级 原理:当写没被持有的时候,则多个进程可以并发持有。 当写持有时,持有线程会被阻塞,获取读的操作也被阻塞。 所以读写,用于读多写少的环境下。...读优先:当读线程 A 先持有了读,写线程 B 获取写的时候,会被阻塞,并且阻塞过程中,后续来的读线程 C 仍然可以成功获取读,最后直到读线程 A 和 C 释放读后,写线程 B 才可以成功获取写...写优先:当读线程 A 先持有了读,写线程 B 获取写的时候,会被阻塞,并且阻塞过程中,后续来的读线程 C 获取读时会失败,于是读线程 C 将被阻塞在获取读的操作,这样只要读线程 A 释放读

49781

万字长文带你了解Java中的分类

轻量级转重量级:当持有轻量级线程无法成功自旋获取时,会将升级为重量级。自旋是指线程获取时会尝试一段时间的忙等待,避免线程阻塞和唤醒带来的开销。...内存占用:每个分段都需要使用额外的内存空间来保存信息和数据,因此会增加系统的内存占用。...自旋 自旋(Spin Lock)是一种忙等待的。因为线程获取时会循环等待,因此它不会主动放弃CPU,而是一直占用CPU资源,直到获取到并完成相应的操作后才会释放CPU资源。...自旋通常由一个标志变量组成,线程获取自旋时会循环检查这个标志变量,如果发现被占用,则不断循环等待,直到标志变量变为可用状态才能获取。...死锁通常在以下情况下可能发生: 互斥资源:当多个线程需要互斥地访问某些资源,而这些资源同一时间只能被一个线程占用时,如果多个线程之间相互等待对方释放资源,就可能发生死锁。

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

AQS这样学就很简单了

核心功能 如果你要实现一套机制保证线程互斥,核心是实现这六个功能:抢、释放、入队、出队、阻塞、唤醒。下面分别说下这六个功能如何实现以及实现的时候需要考虑哪些特殊情况。...抢 如果当前没有任何线程持有,那进来的线程就可以去抢。 因为存在多个线程同时上锁,所以需要通过机制来保证同一时刻只能有一个线程能够操作标志位,这个机制就是CAS。...如果有线程持有,这时候进来的线程如果是持有线程,就发生了重入,需要记录重入次数,因为解锁的时候也要解锁相应的次数;如果不是持有线程,那有两个选择:让线程运行结束、让线程阻塞等其他线程用完再唤醒运行...AQS队列的头结点永远是当前持有线程占用为什么要这样做呢?这就需要对CPU内部结构及工作机制有深入理解,感兴趣的同学可以深入学习下:CLHLock、MCSLock。...唤醒 未抢到线程为了不占用资源阻塞了自己,拿到线程执行完任务需要来唤醒,不然就会出现奇怪的现象:抢到线程执行完任务退出了,未抢到线程全部阻塞在那里等待唤醒。

41490

Java分类总结

以及非可重入NonReentrantLock的源码来对比分析一下为什么非可重入锁在重复调用同步资源时会出现死锁。...独享 & 共享 & 互斥 & 读写 独享/共享就是一种概念,互斥/读写是具体的实现。 独享:该一次只能被一个线程持有。...如果线程T对数据A加上排它后,则其他线程不能再对A加任何类型的。获得排它线程即能读数据又能修改数据。 共享:该可以被多个线程持有。...读写ReadWriteLock 分为读和写多个互斥,读与写互斥,这是由jvm自己控制的,你只要上好相应的即可。...取到写锁线程的数目后,首先判断是否已经有线程持有。如果已经有线程持有(c!

97441

【基本功】不可不说的Java“”事

CAS需要在操作值的时候检查内存值是否发生变化,没有发生变化才会更新内存值。但是如果内存值原来是A,后来变成了B,然后又变成了A,那么CAS进行检查时会发现值没有发生变化,但是实际上是有变化的。...如果是一个不可重入,那么当前线程调用doOthers()之前需要将执行doSomething()时获取当前对象的释放掉,实际上该对象已被当前线程持有,且无法释放。所以此时会出现死锁。...而为什么可重入就可以嵌套调用时可以自动获得呢?我们通过图示和源码来分别解析一下。 还是打水的例子,有多个人在排队打水,此时管理员允许和同一个人的多个水桶绑定。...JDK中的synchronized和JUC中Lock的实现类就是互斥。 共享是指该可被多个线程持有。如果线程T对数据A加上共享后,则其他线程只能对A再加共享,不能加排它。...取到写锁线程的数目后,首先判断是否已经有线程持有。如果已经有线程持有(c!

42720

【基本功】不可不说的Java“”事

CAS需要在操作值的时候检查内存值是否发生变化,没有发生变化才会更新内存值。但是如果内存值原来是A,后来变成了B,然后又变成了A,那么CAS进行检查时会发现值没有发生变化,但是实际上是有变化的。...如果是一个不可重入,那么当前线程调用doOthers()之前需要将执行doSomething()时获取当前对象的释放掉,实际上该对象已被当前线程持有,且无法释放。所以此时会出现死锁。...而为什么可重入就可以嵌套调用时可以自动获得呢?我们通过图示和源码来分别解析一下。 还是打水的例子,有多个人在排队打水,此时管理员允许和同一个人的多个水桶绑定。...JDK中的synchronized和JUC中Lock的实现类就是互斥。 共享是指该可被多个线程持有。如果线程T对数据A加上共享后,则其他线程只能对A再加共享,不能加排它。...取到写锁线程的数目后,首先判断是否已经有线程持有。如果已经有线程持有(c!

46020

【架构师技巧分享】程序员面试美团:面试官突然问Java “”你应该怎么回答?

CAS需要在操作值的时候检查内存值是否发生变化,没有发生变化才会更新内存值。但是如果内存值原来是A,后来变成了B,然后又变成了A,那么CAS进行检查时会发现值没有发生变化,但是实际上是有变化的。...如果是一个不可重入,那么当前线程调用doOthers()之前需要将执行doSomething()时获取当前对象的释放掉,实际上该对象已被当前线程持有,且无法释放。所以此时会出现死锁。...而为什么可重入就可以嵌套调用时可以自动获得呢?我们通过图示和源码来分别解析一下。 还是打水的例子,有多个人在排队打水,此时管理员允许和同一个人的多个水桶绑定。...JDK中的synchronized和JUC中Lock的实现类就是互斥。 共享是指该可被多个线程持有。如果线程T对数据A加上共享后,则其他线程只能对A再加共享,不能加排它。...取到写锁线程的数目后,首先判断是否已经有线程持有。如果已经有线程持有(c!

49300

不可不说的Java“”事

CAS需要在操作值的时候检查内存值是否发生变化,没有发生变化才会更新内存值。但是如果内存值原来是A,后来变成了B,然后又变成了A,那么CAS进行检查时会发现值没有发生变化,但是实际上是有变化的。...如果是一个不可重入,那么当前线程调用doOthers()之前需要将执行doSomething()时获取当前对象的释放掉,实际上该对象已被当前线程持有,且无法释放。所以此时会出现死锁。...而为什么可重入就可以嵌套调用时可以自动获得呢?我们通过图示和源码来分别解析一下。 还是打水的例子,有多个人在排队打水,此时管理员允许和同一个人的多个水桶绑定。...JDK中的synchronized和JUC中Lock的实现类就是互斥。 共享是指该可被多个线程持有。如果线程T对数据A加上共享后,则其他线程只能对A再加共享,不能加排它。...取到写锁线程的数目后,首先判断是否已经有线程持有。如果已经有线程持有(c!

62320

互斥、自旋、读写、悲观、乐观的应用场景

线程的上下文切换的是什么?当两个线程是属于同一个进程,因为虚拟内存是共享的,所以切换时,虚拟内存这些资源就保持不动,只需要切换线程的私有数据、寄存器等不共享的数据。...读写的工作原理是: 当「写」没有被线程持有时,多个线程能够并发地持有,这大大提高了共享资源的访问效率,因为「读」是用于读取共享资源的场景,所以多个线程同时持有也不会破坏共享资源的数据。...所以说,写是独占,因为任何时刻只能有一个线程持有,类似互斥和自旋,而读是共享,因为读可以被多个线程同时持有。...如下图: 而写优先是优先服务写线程,其工作方式是:当读线程 A 先持有了读,写线程 B 获取写的时候,会被阻塞,并且阻塞过程中,后续来的读线程 C 获取读时会失败,于是读线程 C 将被阻塞在获取读的操作...如果能区分读操作和写操作的场景,那读写就更合适了,它允许多个线程可以同时持有,提高了读的并发性。

1.4K40

循序渐进学习 Java 机制

但是如果内存值原来是 A,后来变成了 B,然后又变成了 A,那么 CAS 进行检查时会发现值没有发生变化,但是实际上是有变化的。...首先为什么 Synchronized 能实现线程同步?回答这个问题之前我们需要了解两个重要的概念:“Java 对象头”、“Monitor”。...但是当自旋超过一定的次数,或者一个线程持有,一个自旋,又有第三个来访时,轻量级升级为重量级标志的状态值变为 “10”,Mark Word 中存储的就是指向重量级互斥量)的指针,后面等待线程也要进入阻塞状态...之前我们说过 ReentrantLock 和 synchronized 都是重入,那么我们通过重入 ReentrantLock 以及非可重入 NonReentrantLock 的源码来对比分析一下为什么非可重入锁在重复调用同步资源时会出现死锁...JDK 中的 synchronized 和 JUC 中 Lock 的实现类就是互斥。 共享是指该可被多个线程持有

31620

不可不说的Java“”事

CAS需要在操作值的时候检查内存值是否发生变化,没有发生变化才会更新内存值。但是如果内存值原来是A,后来变成了B,然后又变成了A,那么CAS进行检查时会发现值没有发生变化,但是实际上是有变化的。...如果是一个不可重入,那么当前线程调用doOthers()之前需要将执行doSomething()时获取当前对象的释放掉,实际上该对象已被当前线程持有,且无法释放。所以此时会出现死锁。...而为什么可重入就可以嵌套调用时可以自动获得呢?我们通过图示和源码来分别解析一下。 还是打水的例子,有多个人在排队打水,此时管理员允许和同一个人的多个水桶绑定。...JDK中的synchronized和JUC中Lock的实现类就是互斥。 共享是指该可被多个线程持有。如果线程T对数据A加上共享后,则其他线程只能对A再加共享,不能加排它。...取到写锁线程的数目后,首先判断是否已经有线程持有。如果已经有线程持有(c!

33030

思维导图整理Java并发基础

为了让用户感觉多个线程同时执行的, CPU 资源的分配采用了时间片轮转也就是给每个线程分配一个时间片,线程时间片内占用 CPU 执行任务。...死锁的产生必须具备以下四个条件: 互斥条件:指线程对己经获取到的资源进行它性使用,即该资源同时只由一个线程占用。...其中,互斥这个条件我们没有办法破坏,因为用为的就是互斥。不过其他三个条件都是有办法破坏掉的,到底如何做呢? 对于“请求并持有”这个条件,可以一次性请求所有的资源。...没有公平性需求的前提下尽量使用非公平,因为公平会带来性能开销。 14.3、独占与共享 根据只能被单个线程持有还是能被多个线程共同持有可以分为独占和共享。...共享则可以同时由多个线程持有 ,例如 ReadWriteLock读写,它允许一个资源可以被多线程同时进行读操作。 独占是一种悲观,共享是一种乐观

45220

【C++】C++11 线程

如果当前没有被任何线程持有,则当前线程持有并加锁;如果当前已经被其他线程持有,则当前线程阻塞直到持有线程释放;如果当前互斥量被当前调用线程锁住,则会产生死锁。...如果当前没有被任何线程持有,则当前线程持有并加锁;如果当前已经被其他线程持有,则加锁失败返回 false,但当前线程并不会阻塞,而是跳过临界区代码继续向后执行;如果当前互斥量被当前调用线程锁住,则会产生死锁...,那为什么不只保护 ++g_val。...我们还是以 ++g_val 操作为例,和一般的 ++ 操作不同,CAS 会额外使用一个寄存器来保存讲寄存器中 g_val 修改之前的值 (预期原值),并且将修改之后的值 (新值) 写回到内存时会重新取出内存中...这样可以确保线程等待时不会占用 CPU 资源。 如下,通过条件变量,当 t1/t2 线程条件不满足时,线程就会直接阻塞,让出 CPU 资源,直到被通知唤醒。

32440

看完你就明白的系列之的状态

,而自旋是基于 CAS 机制实现的,CAS又是乐观的一种实现,那么对于来说,多个线程同步访问某个资源的流程细节是否一样呢?...30bit 的内存空间却没有占用,2bit 空间存放标志位为11。...其中无和偏向标志位都是01,只是在前面的1bit区分了这是无状态还是偏向状态。 关于为什么这么分配的内存,我们可以从 OpenJDK 中的markOop.hpp类中的枚举窥出端倪 ?...指令时会计数器减1,当计数器被减到0时,就释放了。...否则说明多个线程竞争,轻量级就要膨胀为重量级标志的状态值变为 10 ,Mark Word中存储的就是指向重量级互斥量)的指针,后面等待线程也要进入阻塞状态。

63930

Redisson 分布式实现之源码篇 → 为什么推荐用 Redisson 客户端

→ Redis 的发布/订阅 与 Lua,方便更好的理解下文 分布式的特点   可以类比 JDK 中的   互斥     不仅要保证同个服务中不同线程互斥,还需要保证不同服务间、不同线程互斥...T2 加的给释放了   公平与非公平     公平多个线程按照申请的顺序去获得,所有线程都在队列里排队,这样就保证了队列中的第一个先得到     非公平多个线程不按照申请的顺序去获得...,直接返回的过期时间   这里有个疑问:为什么 field = uuid + : + threadId,而不是 field = threadId     友情提示下:从多个服务(也就是多个 Redisson...获取的过程中,尝试获取失败(被其他线程占有),则会完成对该锁频道的订阅,订阅过程中线程会阻塞   持有线程释放时会向锁频道发布消息,订阅了该锁频道的线程会被唤醒,继续去获取   这里有个疑问...,保证线程之间的互斥   互斥之后,未获取到线程会订阅锁频道,然后进入一定时长的阻塞   超时   有超时设置,给 hash 结构的 key 加上过期时间,默认是 30s   续期   线程获取到之后会开启一个定时任务

1.4K30

Go语言如何实现可重入

这一篇文章就带你来解密~ 什么是可重入 之前写过java的同学对这个概念应该了如指掌,可重入又称为递归,是指在同一个线程在外层方法获取的时候,进入该线程的内层方法时会自动获取,不会因为之前已经获取过还没释放而阻塞...美团技术团队的一篇关于的文章当中针对可重入进行了举例: 假设现在有多个村民水井排队打水,有管理员正在看管这口水井,村民在打水时,管理员允许和同一个人的多个水桶绑定,这个人用多个水桶打水时,第一个水桶和绑定并打完水之后...总结一下实现一个可重入需要这两点: 记住持有线程 统计重入的次数 统计重入的次数很容易实现,接下来我们考虑一下怎么实现记住持有线程?...这里有一个特别要说明的就是sync.Cond,使用Cond的目的是,当多个Goroutine使用相同的可重入时,通过cond可以对多个协程进行协调,如果有其他协程正在占用,则当前协程进行阻塞,直到其他协程调用释放...为什么Go语言中没有可重入 这问题的答案,我:https://stackoverflow.com/questions/14670979/recursive-locking-in-go#14671462

54630

Java 并发(5)ReentrantLock 源码分析

我们知道 synchronized 关键字实现了内置,而 volatile 关键字保证了多线程内存可见性。...ReentrantLock 类实现了 Lock 接口,并提供了与 synchronized 相同的互斥性和内存可见性,它的底层是通过 AQS 来实现多线程同步的。...每个 Java 对象之所以可以作为,是因为在对象头中关联了一个 monitor 对象 (管程),线程进入同步代码块时会自动持有 monitor 对象,退出时会自动释放 monitor 对象,当 monitor...ReentrantLock 加锁和内存上提供的语义与内置锁相同,此外它还提供了一些其他功能,包括定时的等待,可中断的等待,公平,以及实现非块结构的加锁。...如果同步状态不为 0 表明占用,此时会先去判断持有线程是否是当前线程,如果是的话就将同步状态加 1,否则的话这次尝试获取的操作宣告失败。

44130

线程知识点总结

进入这个状态后,是不能自动唤醒的,必须依靠其他线程调用notify()或notifyAll()方法才能被唤醒, (2)、同步阻塞:运行的线程获取对象的同步时,若该同步被别的线程占用,则JVM会把该线程放入...:创建线程的工厂 handler:拒绝策略 死锁 线程死锁是指由于两个或者多个线程互相持有对方所需要的资源,导致这些线程处于等待状态,无法执行。...死锁解决办法:不要在同步中嵌套同步 检查死锁方式 Jstack命令 JConsole工具 synchronized 解决可见性: 获得互斥(同步获取) 清空本地内存 从主内存拷贝变量的最新副本到本地内存...执行代码 将更改后的共享变量的值刷新到主内存 释放互斥 同步原理: 普通同步方法,是当前实例对象this 静态同步方法,是当前类的class对象 同步方法块,是括号里面的对象 synchronized...独占意味着其他线程只能依靠阻塞来等待线程释放。而在CPU转换线程阻塞时会引起线程上下文切换,当有很多线程竞争的时候,会引起CPU频繁的上下文切换导致效率很低。而Lock用的是乐观方式。

59520

不可不说的 Java “”事

如果是一个不可重入,那么当前线程调用doOthers()之前需要将执行doSomething()时获取当前对象的释放掉,实际上该对象已被当前线程持有,且无法释放。所以此时会出现死锁。...而为什么可重入就可以嵌套调用时可以自动获得呢?我们通过图示和源码来分别解析一下。 还是打水的例子,有多个人在排队打水,此时管理员允许和同一个人的多个水桶绑定。...的源码来对比分析一下为什么非可重入锁在重复调用同步资源时会出现死锁。...JDK 中的synchronized和 JUC 中Lock的实现类就是互斥。 共享是指该可被多个线程持有。...取到写锁线程的数目后,首先判断是否已经有线程持有。如果已经有线程持有(c!

32730

线程安全与优化

同步是指在多个线程并发访问共享数据时,保证共享数据同一个时刻只被一条(或者是一些, 当使用信号量的时候)线程使用。...如果这个对象没被锁定,或者当前线程已经持有了那个对象的,就把的计数器的值增加一,而在执行monitorexit指令时会计数器的值减一。一旦计数器的值为零,随即就被释放了。...公平:是指多个线程等待同一个时,必须按照申请的时间顺序来依次获得;而非公平则不保证这一点,被释放时,任何一个等待线程都有机会获得。...(Biased Locking) 自旋与自适应自旋 如果物理机器有多个处理器核心,能让两个或以上的线程同时并行执行,我们就可以让后面请求的那个线程“稍等一会”,但不放弃处理器的执行时间,看看持有线程是否很快就会释放...自旋等待不能代替阻塞,且先不说对处理器数量的要求,自旋等待本身虽然避免了线程切换的开销,但要占用处理器时间的,所以如果占用的时间很短,自旋等待的效果就会非常好,反之如果占用的时间很长,那么自旋的线程只会白白消耗处理器资源

31364
领券