Java中有互斥体吗?
java中有互斥对象或者创建互斥对象的方法吗? 我这么问是因为用 1 个许可证初始化的信号量对象对我没有帮助。 考虑这种情况:
try {
semaphore.acquire();
//do stuff
semaphore.release();
} catch (Exception e) {
semaphore.release();
}
如果第一次获取时发生异常,则catch块中的释放将增加许可,并且信号量不再是二进制信号量。
正确的方法会是吗?
try {
semaphore.acquire();
//do stuff
} catch (Exception e) {
//exception stuff
} finally {
semaphore.release();
}
上面的代码能确保信号量是二进制的吗?
Is there a Mutex object in java or a way to create one?
I am asking because a Semaphore object initialized with 1 permit does not help me.
Think of this case:
try {
semaphore.acquire();
//do stuff
semaphore.release();
} catch (Exception e) {
semaphore.release();
}
if an exception happens at the first acquire, the release in the catch block will increase the permits, and the semaphore is no longer a binary semaphore.
Will the correct way be?
try {
semaphore.acquire();
//do stuff
} catch (Exception e) {
//exception stuff
} finally {
semaphore.release();
}
Will the above code ensure that the semaphore will be binary?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
Java 中的任何对象都可以通过
synchronized
块用作锁。当异常发生时,这也会自动释放锁。您可以在此处阅读有关此内容的更多信息:内在锁和同步
Any object in Java can be used as a lock using a
synchronized
block. This will also automatically take care of releasing the lock when an exception occurs.You can read more about this here: Intrinsic Locks and Synchronization
请参阅此页面:http://www.oracle.com/technetwork/articles /javase/index-140767.html
它有一个稍微不同的模式,这是(我认为)您正在寻找的:
在这种用法中,您仅在之后调用
release()
成功的acquire()
See this page: http://www.oracle.com/technetwork/articles/javase/index-140767.html
It has a slightly different pattern which is (I think) what you are looking for:
In this usage, you're only calling
release()
after a successfulacquire()
没有人明确提到这一点,但这种模式通常不适合信号量。原因是任何线程都可以释放信号量,但您通常只想要< em>所有者线程最初锁定以便能够解锁。对于这个用例,在Java中,我们通常使用ReentrantLocks,它可以这样创建:
而通常的使用设计模式是:
这里是 Java 源代码中的一个示例,您可以在其中看到此模式的实际应用。
可重入锁还有支持公平性的额外好处。
仅当需要非所有权释放语义时才使用信号量。
No one has clearly mentioned this, but this kind of pattern is usually not suited for semaphores. The reason is that any thread can release a semaphore, but you usually only want the owner thread that originally locked to be able to unlock. For this use case, in Java, we usually use ReentrantLocks, which can be created like this:
And the usual design pattern of usage is:
Here is an example in the java source code where you can see this pattern in action.
Reentrant locks have the added benefit of supporting fairness.
Use semaphores only if you need non-ownership-release semantics.
我认为你应该尝试使用:
虽然信号量初始化:
并且在你的
Runnable Implementing
中I think you should try with :
While Semaphore initialization :
And in your
Runnable Implementation
原帖中的错误是在 try 循环内设置了 acquire() 调用。
这是使用“二进制”信号量(互斥体)的正确方法:
Mistake in original post is acquire() call set inside the try loop.
Here is a correct approach to use "binary" semaphore (Mutex):
每个对象的锁与互斥/信号量设计略有不同。
例如,没有办法正确地实现通过释放前一个节点的锁并捕获下一个节点来遍历链接节点。但是使用 mutex 就很容易实现:
目前
java.util.concurrent
中没有这样的类,但是您可以在这里找到 Mutext 实现Mutex.java。至于标准库,Semaphore 提供了所有这些功能以及更多功能。Each object's lock is little different from Mutex/Semaphore design.
For example there is no way to correctly implement traversing linked nodes with releasing previous node's lock and capturing next one. But with mutex it is easy to implement:
Currently, there is no such class in
java.util.concurrent
, but you can find Mutext implementation here Mutex.java. As for standard libraries, Semaphore provides all this functionality and much more.要确保信号量是二进制的,您只需确保在创建信号量时传入的许可数为 1。 Javadocs 有一点更多解释。
To ensure that a
Semaphore
is binary you just need to make sure you pass in the number of permits as 1 when creating the semaphore. The Javadocs have a bit more explanation.