Java信号量停止线程

3

大家下午好,

我正在为学校项目使用Java的信号量和并发,关于它的工作原理有几个问题!

如果没有可用的许可证,我需要使线程退出 "队列" - 而不仅仅是睡眠,直到有一个准备好。这可能吗?就像您在我的try、catch、finally中看到的 - 没有处理此事件的方法:

try {
    semaphore.acquire();
    System.out.println(Thread.currentThread().getName() + " aquired for 3 seconds " + semaphore.toString());
    Thread.sleep(3000);
}
catch (InterruptedException e) {
   e.printStackTrace();
} finally {   
   semaphore.release();
   System.out.println(Thread.currentThread().getName() + " released " + semaphore.toString());
}

Daniel提到了tryAquire函数 - 这看起来很不错,但我读过的教程都说信号量需要一个try, catch, finally块来防止死锁。我的当前代码(实现了tryAquire)将在finally块中释放,即使该线程从未被获取。你有什么建议吗?

public void seatCustomer(int numBurritos) {
    try {
        if(semaphore.tryAcquire()) {
            System.out.println(Thread.currentThread().getName() + " aquired for 3 seconds " + semaphore.toString());
            Thread.sleep(3000); 
        } else {
            System.out.println(Thread.currentThread().getName() + " left due to full shop");
        }

    }
    catch (InterruptedException e) {
       e.printStackTrace();
    } finally {   
       semaphore.release();
       System.out.println(Thread.currentThread().getName() + " released " + semaphore.toString());
    }
}
1个回答

4

我建议您阅读Semaphor的JavaDocs。特别是要看tryAcquire方法。

从此信号量获取许可,仅在调用时有一个可用。

获取许可,如果一个可用并立即返回true值,则将可用许可数减少1。

如果没有许可证可用,则此方法将立即返回false值。

这意味着您可以尝试获取可用的许可证。如果没有可用的许可证,则此方法会立即返回false值,而不是阻塞。

您需要使“finally”块更加智能。

boolean hasPermit = false;
try {
    hasPermit = semaphore.tryAcquire();
    if (hasPermit) {
        // do stuff.
    }
} finally {
    if (hasPermit) {
       semaphore.release();
    }
}

谢谢Daniel!这就是我一直在尝试的,但我的try/catch/finally块会释放从未获取的线程=/ - Nathan_Sharktek
我已经更新了我的答案,包括如何在finally块中处理它。 - Daniel
太好了——非常感谢你的帮助,@Daniel。 - Nathan_Sharktek

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接