如何在Java中有条件地锁定?
我一直在利用Java的如何在Java中有条件地锁定?,java,locking,synchronized,Java,Locking,Synchronized,我一直在利用Java的synchronized块使我的部分代码线程安全。我正在向java移植一个数据结构,它通常可以使用synchronized块,但我并不总是知道如何以典型的java方式使用它们 以下是一个场景的示例: myMethod (Bool useLock) { if (useLock) { //locks the following section of code until unlocked. lockObject.l
synchronized
块使我的部分代码线程安全。我正在向java移植一个数据结构,它通常可以使用synchronized
块,但我并不总是知道如何以典型的java方式使用它们
以下是一个场景的示例:
myMethod (Bool useLock)
{
if (useLock)
{
//locks the following section of code until unlocked.
lockObject.lock();
}
//do more stuff....
if (useLock)
{
//unlocks exclusive control of code.
lockObject.unlock();
}
}
如何在Java中实现类似的功能?在这段代码中,有时我想锁定,有时我不想锁定,但我想聪明一点,不必编写同一代码的两个版本。除了使用
同步的
块,Java中还有其他锁定方法吗?您可以使用不安全的方法来监视进入和监视退出,但这是一个坏主意
如果不需要锁,JVM几乎会在任何情况下优化它们synchronized
在只有一个线程获得它时非常有效。(与锁不同,例如)
除了使用同步块,Java中还有其他锁定方法吗
是的-,尤其是ReentrantLock
类,但是正如Peter所说,如果您可以不使用synchronized
,那么总体来说它可能会更高效(并且更易于维护,特别是当您作为团队的一部分工作时)。您可以使用锁对象,尤其应该使用锁对象
或者您仍然可以使用同步的块来解决问题。您问题中的代码如下所示:
myMethod (Bool useLock) {
if (useLock) {
synchronized (this) {
criticalSection();
}
} else {
criticalSection();
}
}
criticalSection() {
//do more stuff....
}
或者,如果要保证类的不同实例之间的互斥性,则应使用除此之外的其他监视对象。例如classname.class
或该类的其他明确定义的静态变量。我猜可以在您的场景中使用
final Lock lock = new ReentrantLock();
示例代码段
class X {
private final ReentrantLock lock = new ReentrantLock();
// ...
public void m() {
lock.lock(); // block until condition holds
try {
// ... method body
} finally {
lock.unlock()
}
}
}
您可以使用Java对象和对象Condition
class'java文档也给出了一个非常好的isFull
和isEmpty
示例
在您的情况下,我想,您可以使用condition对象使代码更可读/更容易理解。大概是这样的:
final Lock lock = new ReentrantLock();
final Condition useLock = lock.newCondition();
并使用适当的条件 已经发布了一些不错的答案,但我想添加另一个适合我的解决方案:
我从以下几点开始:
...
synchronized(<lockobject>) {
<huge section of code with lots of variables>
}
...
。。。
同步的(){
}
...
将其更改为:
...
synchronized(<condition> ? <lockobject> : new Object()) {
<huge section of code with lots of variables>
}
...
。。。
已同步(?:新对象(){
}
...
基本上,如果条件为true,它将使用lockobject上的synchronized执行代码,但如果条件为false,它将使用“new Object()”,这基本上允许它在不进行任何同步的情况下运行。他已经指定了要锁定的对象:lockobject
。而且Bool
不是标准的Java类。我最终使用了您的同步解决方案。我看了ReentrantLock的,谢谢!但它们似乎并不相互排斥同步块。