Java中有互斥体吗?

发布于 2024-10-22 00:46:17 字数 466 浏览 7 评论 0原文

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

如果没结果 2024-10-29 00:46:17

Java 中的任何对象都可以通过 synchronized 块用作锁。当异常发生时,这也会自动释放锁。

Object someObject = ...;

synchronized (someObject) {
  ...
}

您可以在此处阅读有关此内容的更多信息:内在锁和同步

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.

Object someObject = ...;

synchronized (someObject) {
  ...
}

You can read more about this here: Intrinsic Locks and Synchronization

三人与歌 2024-10-29 00:46:17

请参阅此页面:http://www.oracle.com/technetwork/articles /javase/index-140767.html

它有一个稍微不同的模式,这是(我认为)您正在寻找的:

try {
  mutex.acquire();
  try {
    // do something
  } finally {
    mutex.release();
  }
} catch(InterruptedException ie) {
  // ...
}

在这种用法中,您仅在之后调用 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:

try {
  mutex.acquire();
  try {
    // do something
  } finally {
    mutex.release();
  }
} catch(InterruptedException ie) {
  // ...
}

In this usage, you're only calling release() after a successful acquire()

神魇的王 2024-10-29 00:46:17

没有人明确提到这一点,但这种模式通常不适合信号量。原因是任何线程都可以释放信号量,但您通常只想要< em>所有者线程最初锁定以便能够解锁。对于这个用例,在Java中,我们通常使用ReentrantLocks,它可以这样创建:

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

private final Lock lock = new ReentrantLock(true);

而通常的使用设计模式是:

  lock.lock();
  try {
      // do something
  } catch (Exception e) {
      // handle the exception
  } finally {
      lock.unlock();
  }

这里是 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:

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

private final Lock lock = new ReentrantLock(true);

And the usual design pattern of usage is:

  lock.lock();
  try {
      // do something
  } catch (Exception e) {
      // handle the exception
  } finally {
      lock.unlock();
  }

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.

已下线请稍等 2024-10-29 00:46:17
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;


private final Lock _mutex = new ReentrantLock(true);

_mutex.lock();

// your protected code here

_mutex.unlock();
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;


private final Lock _mutex = new ReentrantLock(true);

_mutex.lock();

// your protected code here

_mutex.unlock();
哥,最终变帅啦 2024-10-29 00:46:17

我认为你应该尝试使用:

虽然信号量初始化:

Semaphore semaphore = new Semaphore(1, true);

并且在你的Runnable Implementing

try 
{
   semaphore.acquire(1);
   // do stuff

} 
catch (Exception e) 
{
// Logging
}
finally
{
   semaphore.release(1);
}

I think you should try with :

While Semaphore initialization :

Semaphore semaphore = new Semaphore(1, true);

And in your Runnable Implementation

try 
{
   semaphore.acquire(1);
   // do stuff

} 
catch (Exception e) 
{
// Logging
}
finally
{
   semaphore.release(1);
}
晌融 2024-10-29 00:46:17

原帖中的错误是在 try 循环内设置了 acquire() 调用。
这是使用“二进制”信号量(互斥体)的正确方法:

semaphore.acquire();
try {
   //do stuff
} catch (Exception e) {
   //exception stuff
} finally {
   semaphore.release();
}

Mistake in original post is acquire() call set inside the try loop.
Here is a correct approach to use "binary" semaphore (Mutex):

semaphore.acquire();
try {
   //do stuff
} catch (Exception e) {
   //exception stuff
} finally {
   semaphore.release();
}
妥活 2024-10-29 00:46:17

每个对象的锁与互斥/信号量设计略有不同。
例如,没有办法正确地实现通过释放前一个节点的锁并捕获下一个节点来遍历链接节点。但是使用 mutex 就很容易实现:

Node p = getHead();
if (p == null || x == null) return false;
p.lock.acquire();  // Prime loop by acquiring first lock.
// If above acquire fails due to interrupt, the method will
//   throw InterruptedException now, so there is no need for
//   further cleanup.
for (;;) {
Node nextp = null;
boolean found;
try { 
 found = x.equals(p.item); 
 if (!found) { 
   nextp = p.next; 
   if (nextp != null) { 
     try {      // Acquire next lock 
                //   while still holding current 
       nextp.lock.acquire(); 
     } 
     catch (InterruptedException ie) { 
      throw ie;    // Note that finally clause will 
                   //   execute before the throw 
     } 
   } 
 } 
}finally {     // release old lock regardless of outcome 
   p.lock.release();
} 

目前 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:

Node p = getHead();
if (p == null || x == null) return false;
p.lock.acquire();  // Prime loop by acquiring first lock.
// If above acquire fails due to interrupt, the method will
//   throw InterruptedException now, so there is no need for
//   further cleanup.
for (;;) {
Node nextp = null;
boolean found;
try { 
 found = x.equals(p.item); 
 if (!found) { 
   nextp = p.next; 
   if (nextp != null) { 
     try {      // Acquire next lock 
                //   while still holding current 
       nextp.lock.acquire(); 
     } 
     catch (InterruptedException ie) { 
      throw ie;    // Note that finally clause will 
                   //   execute before the throw 
     } 
   } 
 } 
}finally {     // release old lock regardless of outcome 
   p.lock.release();
} 

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.

顾冷 2024-10-29 00:46:17

要确保信号量是二进制的,您只需确保在创建信号量时传入的许可数为 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文