Semaphore拿到执行权的线程之间是否互斥?

信号量,这个东西可以控制几个线程同时运行。
2 02 2 年,当我从事这个项目时,我会使用它。
具体来说就是Semaphore,它是一个同步工具。
如果指定一个数字,例如newSemaphore(1 ),则意味着最多有一个线程可以查看它。
想一想:如果权限的数量只有1 ,那岂不是就像锁了一个互斥锁一样?
我举了一个例子:在一个城市中,信号量必须管理​​三个共享资源。
首先我让 T1 线程开始运行。
它接收信号量并开始执行任务。
然后线程 T2 等待。
当T1 完成时,它返回信号量以便T2 可以进入。
这就是它的意思。

确保相互排他性——防止混乱。
想想看,如果两个线程同时进入的话,数据肯定会混在一起。
这就是信号量的作用。
这保证了任何时候只有一个线程可以获取信号量并访问共享资源。
2 02 2 年,我测试了很久,结果是第一个T1 进来,完成工作,然后离开。
然后T2 进入,完成他的工作并再次退出。
就是这样,没有两根线会互相接触。

Qt开发-多线程间的互斥

JAVA中线程在什么时候需要同步和互斥

上周,一位客户问我关于Java并发的问题,这让我很困惑。
让我们把它分解掉,不要去对付那些虫子。

1 .为什么要同步? 你是对的,最主要的是保护资源免遭破坏。
想象一下两个线程想要改变同一个对象的同一个域,那肯定会很混乱。
例如,在2 02 3 年的上海一家购物中心,如果两个收银员同时扫描同一种商品,价格几乎肯定会计算错误。
同步的目的就是防止这些同步问题,保证数据的一致性。

2 锁怎么用? 你也说得对,锁就是钥匙。
每个 Java 对象(除了 null)都有一个内置锁。
当线程访问对象或代码块的同步方法时,它必须首先获取此锁。
对于获得锁的线程来说,在释放锁之前,其他线程无法进入该对象的同步方法。
就像在商场收银台一样,您一次只能为一位顾客服务。

3 静态锁和对象锁是不同的。
这一点尤其重要!静态方法锁是针对类的,即类对象。
例如,MyClass.staticMethod() 使用 MyClass.class 锁。
对象锁是该特定对象的一个​​实例。
当线程处于静态同步方法中时,它会获取类锁;然后它调用另一个对象的synchronized方法,这时候它就得拿这个对象的锁。
两个锁互不影响。
2 02 2 年我在北京做一个公司项目,犯了这个错误。
显然,线程是静态的,结果我去获取对象锁,导致其他人无法进入,卡住了一段时间。

4 关键是要留意锁的位置。
是的,这就是本质。
你必须知道哪个对象被 async(this) 或 async(staticMethod) 锁定。
如果你感到困惑,你就会有麻烦。

5 编写线程安全类 这部分是真实的。
你必须清楚地考虑哪些地方同时被访问。
例如,当更新计数器时,count++实际上并不是一个原子操作。
一个线程读取计数,另一个线程也读取计数,都加1 ,但结果只加1 这时候就必须使用AtomicInteger等原子类,或者加锁来保护它。
它确保在原子过程期间没有其他人可以进入。
我遇到的困境是我认为 Map.put(key, value) 是一个原子操作。
结果,两个线程同时运行,并且某个特定的键被覆盖。

6 等待锁定它将被阻止。
是的,线程在队列中等待,没有获得锁。
就像我们在操作系统课上学到的或者FCFS或者一些算法一样。

7 死胡同 你说的基本是对的,死锁其实是一个小概率事件。
但一旦出现这种情况,软件就会卡住并且无法恢复。
死锁是指线程A持有锁1 ,正在等待锁2 ;线程B持有锁2 ,等待锁1 ,两人互相等待,谁也没有放手。
有时候写一个死锁测试程序不一定行得通,因为JVM调度器或者系统资源可能会在某个时刻帮你解决。
但一旦出现问题,那绝对是一场灾难。

其他风险和想法: 你是对的,锁仍然存在死锁的风险,尤其是当顺序错误的时候。
比如先取A后B,一个线程先取A后B,另一个线程先取B后A。
还有粗粒度的锁,适合简单的操作,比如计数器。
但细粒度的控制很烦人。
例如,如果我想同时保护两个变量并使用两个锁,则可能无法获取一个锁,而必须更改另一个变量。
如今先进的CPU可能有一些支持细粒度锁的机制,但锁一般还是用在Java层面。

无论如何,你可以找到答案。
关键是要了解锁的性质,不要盲目使用。