gpt4 book ai didi

java - 使用信号量的死锁

转载 作者:行者123 更新时间:2023-11-30 08:11:33 24 4
gpt4 key购买 nike

我有一个关于管理线程的简单问题。我有 3 个进程共享同一个信号量和一个许可。在正常情况下,第一个进程获取此许可并释放两个许可至第二个进程。第二个进程发布 3 允许第三个进程。我举了一个例子来说明我的问题。

第一个:

public class Process0 extends Thread{

Semaphore s;

public Process0(Semaphore s){
this.s = s;
}

public void run(){
try {
sleep(20000);
s.acquire();

System.out.println("hello");
} catch (InterruptedException ex) {
Logger.getLogger(Process.class.getName()).log(Level.SEVERE, null, ex);
}

s.release(2);
}
}

第二个过程:

public class Process1 extends Thread{

Semaphore s;

public Process1(Semaphore s){
this.s = s;
}

public void run(){
try {
this.sleep(10000);
s.acquire(2);
System.out.println("Hello 2");
} catch (InterruptedException ex) {
Logger.getLogger(Process1.class.getName()).log(Level.SEVERE, null, ex);
}

s.release(3);
}

最后一个:

    public class Process2 extends Thread{

Semaphore s;

public Process2(Semaphore s){
this.s = s;
}

public void run(){
try {

System.out.println("Acquire process 3 ");
s.acquire(3);

System.out.println("Hello 3");
} catch (InterruptedException ex) {
Logger.getLogger(Process2.class.getName()).log(Level.SEVERE, null, ex);
}

}

}

问题是。当我运行这三个进程并确保进程 3 是第一个执行 acquire 的进程时。我会陷入僵局。进程 2 从不打印“Hello 3”,进程 1 从不打印“Hello 2”。为什么?

信号量 s = 新信号量(1);

Process0 p = new Process0(s);
Process1 p1 = new Process1(s);
Process2 p2 = new Process2(s);
p.start();
p1.start();
p2.start();

最佳答案

您的信号量构造为 new Semaphore(1) ,它只能获得一份许可证。来电s.acquire(3)永远不会返回,因为信号量永远不会有三个可用的许可。尝试通过Process获得单一许可也阻止因为收购被订购和Process2 “第一”到达:

release方法 javadoc 声明在以下情况下可能会发生获取

Some other thread invokes the release() method for this semaphore and the current thread is next to be assigned a permit.

这个最小的单线程示例将向您展示:

Semaphore s = new Semaphore(1);
s.acquire(2);
System.out.println("Didn't deadlock!");

解决方案是使用 Semaphore.acquire()需要一份许可证,或 Semaphore.acquire(1)这也只需要一个许可证。

您还需要确保获得和释放相同数量的许可,除非您有非常充分的理由滥用 Semaphore .来自 Javadoc:

There is no requirement that a thread that releases a permit must have acquired that permit by calling acquire [or that a thread releases all of its permits]. Correct usage of a semaphore is established by programming convention in the application.

此外,您似乎可能为此任务使用了错误的同步器。你可以使用 CyclicBarrier或其他class usable for synchronization .

关于java - 使用信号量的死锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30935298/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com