gpt4 book ai didi

java - 线程-使用标志解锁锁,然后尝试/最终

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:05:52 26 4
gpt4 key购买 nike

我正在尝试同步3个线程。他们每个人都处理一条履带,该履带沿着自己的路径移动。
不幸的是,他们的道路像这样越过:

为了实现这个目标,我使用了锁。有两个共享块的部分:水平和垂直(我在上面和下面将其命名)。问题在于,一个线程要同时位于两个共享部分中。

我的问题是:

我可以使用标志解锁try/finally子句中的锁吗?

我的意思是,当线程在try/finally子句中解锁锁时,会设置一个标志,并在finally子句中检查是否设置了该标志,然后不会再次解锁。我认为这是一个安全的解决方案,但也许我错了。

还有其他同步线程的方法吗?

这是我的代码:(几乎可以正常工作)

public void moveForward() throws InterruptedException {
redIsUpofAbove();
int choose= 0;
if (Route.critcalSectionAbove.contains(head))
choose= 1;
if (Route.critcalSectionBelow.contains(head))
choose= 2;

switch (choose) {
case 1: {
boolean flag = true;
System.err.println(name + " Lock above");
synchronization.aboveLock.lock();
try {

takeNextGrid();
Thread.sleep(sleepValue);
while (isInAboveCriticalSection()) {
takeNextGrid();
Thread.sleep(sleepValue);
if (isInBelowCriticalSection()) {// Caterpillar is on two
// shared sections
System.out.println(name + " Lock below");
if (!synchronization.belowLock.tryLock()) {

synchronization.aboveLock.unlock();
System.out.println(name + " Unlock above");
synchronization.belowLock.lock();
flag = false;
}
try {
while (isInBelowCriticalSection()) {
takeNextGrid();
if (!isInAboveCriticalSection() && flag) {
synchronization.aboveLock.unlock();
flag = false;
System.out.println(name + " Unlock above");
}
Thread.sleep(sleepValue);
}
} catch (Exception e) {
} finally {
synchronization.belowLock.unlock();
System.err.println(name + "Unlock belovelock");
}
}
}
} catch (Exception e) {
} finally {
if (flag) {
synchronization.aboveLock.unlock();
System.out.println(name + " unlock above");
}
}

break;
}
case 2: {
boolean flag = true;
System.err.println(name + " Lock below");
synchronization.belowLock.lock();
try {

takeNextGrid();
Thread.sleep(sleepValue);
while (isInBelowCriticalSection()) {
takeNextGrid();
Thread.sleep(sleepValue);
if (isInAboveCriticalSection()) {
if (!synchronization.aboveLock.tryLock() && flag) {
synchronization.belowLock.unlock();
System.out.println(name + " Unlock below");
synchronization.aboveLock.lock();
flag = false;
}
try {
System.out.println(name + " Lock above");
while (isInAboveCriticalSection()) {
takeNextGrid();
if (!isInBelowCriticalSection() && flag == true) {
synchronization.belowLock.unlock();
flag = false;
System.out.println(name + " Lock below");
}
Thread.sleep(sleepValue);
}
} catch (Exception e) {

} finally {
synchronization.aboveLock.unlock();
System.err.println(name + "Lock abovelock");
}

}
}
} catch (Exception e) {

} finally {
if (flag) {
synchronization.belowLock.unlock();
System.out.println("Opuszczam belowLock");
}
}

break;
}
default: {
takeNextGrid();
break;
}
}

}

最后一个问题:

在等待锁定锁的线程上,是否有办法设置唤醒优先级?

最佳答案

Can I unlock a lock inside try/finally clause using a flag?



假设您在 InterruptException调用与设置标志之间没有收到 lock(),那么这应该可以正常工作;但是,在给定的上下文中,我认为这没有任何意义。

如果遇到异常,毛毛虫会发生什么?它消失了吗?如果即使在引发异常之后它仍位于路径上的同一位置,则它仍占据路径的该部分;因此,释放锁没有任何意义。

Is there any other way to synchronize the threads?



当然,您还可以尝试其他同步机制(原子,监视器锁定等),但这似乎并不是性能至关重要的应用程序,因此,我只会使用最适合您的方法。如果锁有意义,则使用锁。

现在,如果您要问是否有另一种同步方式(即在路径上用于互斥的另一种策略),那么我对此有一个建议:

caterpillar tracks with 4 critical sections

您当前的解决方案有一个明显的死锁问题。由于 belowabove部分是分别获取的,因此蓝色毛毛虫(G2,“蓝色”)可以获取下部区域并进入,同时红色毛毛虫(G1,“红色”)可以获取上部区域现在,任何一条毛毛虫都无法完成其路线-它们陷入僵局(G1无法前进到下部,而G2无法前进到上部)。

通过将路径划分为多个关键部分(如我的图像所示),并在进入关键部分时获取多个部分,则可以避免这种死锁情况。

只要确保“关键T”中最多有2个毛毛虫(即所有4个关键区域的并集),那么您就可以始终避免死锁。您可以通过创建具有2个许可的 counting semaphore来做到这一点。在获取路径中第一个关键区域的锁之前需要 acquire(),在离开该区域后的某个时间需要 release()。例如,对于红色,顺序为:

sempahore上的
  • acquire()
  • lock()在上面,并通过它前进
  • lock()左下方
  • 信号量上的
  • release()
  • 继续进入中心,然后左下
  • 一旦红色的尾部离开中心,unlock()
  • 上方
    一次,当红尾部离开左下方时, unlock()左下方时
  • 继续前进通过非关键区域...

  • 注意,我们不需要显式锁定Center,因为它由信号灯和其他锁隐式保护。

    显然,可以使用其他方法来确保“临界T”中只有2个毛毛虫,但是信号量似乎是执行此操作的最简单方法。

    此解决方案可避免死锁,如下所示:
  • 如果红色位于上方,蓝色位于右下方,那么蓝色会阻塞,直到它可以获取上方,然后才能进入中心,从而允许红色首先退出关键区域。
  • 如果蓝​​色位于右下方,绿色位于左下方,则绿色会阻塞,直到它可以进入右下方,然后才能进入中心,从而允许蓝色首先退出关键区域。
  • 如果绿色位于左下方,而红色位于上方,则红色会阻塞,直到它可以进入左下方,然后才能进入中心,从而允许绿色首先退出关键区域。

  • 所有其他可能的配置也将避免死锁,这只是三个最有趣的情况。

    Is there a way to set a priority to wake up, on threads which are waiting on a locked lock?



    我不知道Java库中实际上会给您这样的优先级保证的任何工具。您要么必须找到执行此操作的第三方库,要么要实现自己的库。

    一个简单的方法就是不要为毛毛虫使用单独的线程。您可以使用单个线程来完成所有的毛毛虫逻辑-没有理由为每个毛毛虫都需要一个线程。如果您在一个线程中拥有所有逻辑,那么处理毛毛虫的顺序将为您带来隐式的优先级排序。

    关于java - 线程-使用标志解锁锁,然后尝试/最终,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37526271/

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