由不同的线程

时间:2015-12-01 11:19:37

标签: java multithreading concurrency transactions locking

我正在一台服务器上实施乐观交易(BOCC)。在提交时,读取和写入集合将根据当前数据库状态进行验证(如果自读取后状态已更改,则事务将中止)。如果验证成功,则所有对象都将写入数据库。

不同对象集上的验证(以及数据库更新)可以是并发的,但必须使用读写锁来保护重叠的对象集。

我使用ReentrantReadWriteLock来确保验证,这很正常。现在我正在编写一个恢复机制,如果由于某些错误(在验证之后)而不是所有写入数据库的对象都会重复更新过程。

因此,恢复会重复数据库写入,然后尝试释放锁定(恢复成功后)。问题是我尝试从另一个线程释放锁(因为恢复是由另一个后台服务执行的),这会引发IllegalMonitorStateExceptionunlock方法的注释会验证此行为。

    /**
     * Attempts to release this lock.
     *
     * <p>If the current thread is the holder of this lock then
     * the hold count is decremented. If the hold count is now
     * zero then the lock is released.  If the current thread is
     * not the holder of this lock then {@link
     * IllegalMonitorStateException} is thrown.
     *
     * @throws IllegalMonitorStateException if the current thread does not
     * hold this lock
     */
    public void unlock() {

现在我的问题是:如果我需要,可以使用Java中的锁:

  • 释放锁,而不依赖于获取它们的线程。
  • 具有读写锁(以及可能从读写升级)
  • 不要等待(阻止)锁定(我只使用tryLock)?

3 个答案:

答案 0 :(得分:2)

StampedLock为我做了诀窍,可以从另一个线程解锁。我用它作为:

ReadWriteLock lock = new StampedLock().asReadWriteLock();

答案 1 :(得分:1)

一般来说,从一个不同的线程向声明锁定的线程释放锁是个坏主意。这样做会打开各种竞争条件和其他意外行为。例如,如果最初声称锁定的线程开始对事物进行更改,会发生什么情况,因为它不知道其他线程已处理它并释放锁定?

而是向原始线程发送一个信号,说明它已被处理,并释放锁定。

$tempnewpw确实会让你试图锁定而无需等待。

Restore from local history http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/locks/ReentrantReadWriteLock.html似乎可以满足您的需求,只需发出信号即可释放锁定。

您需要在原始线程上执行重试或让原始线程等待(持有锁),直到重试完成,然后自行释放它们。只有声称锁定的线程才能释放它,这几乎是一个通用的线程规则,因此不会有很多替代选项。

除非您想要实现自己的锁定(例如,最基本级别的AtomicBoolean可以被认为是写锁定,而读取锁定则是AtomicInteger)。这是你可能会开放的一大堆蠕虫。正确地进行线程和同步 hard

答案 2 :(得分:1)

正如@TimB指出的那样,一个线程释放(即打破)另一个线程的锁定是一般来说的危险事情。

但是,如果要在允许的情况下实现自定义锁定,则应该能够执行此操作。如果您查看git config --global http.proxy http://username:password@proxy.server.com:8080 git config --global https.proxy http://username:password@proxy.server.com:8080 //Replace username with your proxy username //Replace password with your proxy password //Replace proxy.server.com with the proxy domain URL. //Replace 8080 with the proxy port no configured on the proxy server. 的实现(例如here),java.util.concurrent.locks.ReentrantReadWriteLock将实现释放锁定的逻辑。如果你检查它,它实际上正在执行你正在讨论的检查,并在代码中显式抛出异常。虽然我不会想象这将是一件简单的事情,但它应该是可能的 将该行为更改为适合您框架的内容。

我是否知道任何现有的&#34;易碎的&#34;锁定实施?不,我在GrepCode中找不到一个。

为什么呢?可能是因为其他人怀疑锁定的效用(和安全性)。