我正在一台服务器上实施乐观交易(BOCC)。在提交时,读取和写入集合将根据当前数据库状态进行验证(如果自读取后状态已更改,则事务将中止)。如果验证成功,则所有对象都将写入数据库。
不同对象集上的验证(以及数据库更新)可以是并发的,但必须使用读写锁来保护重叠的对象集。
我使用ReentrantReadWriteLock
来确保验证,这很正常。现在我正在编写一个恢复机制,如果由于某些错误(在验证之后)而不是所有写入数据库的对象都会重复更新过程。
因此,恢复会重复数据库写入,然后尝试释放锁定(恢复成功后)。问题是我尝试从另一个线程释放锁(因为恢复是由另一个后台服务执行的),这会引发IllegalMonitorStateException
。 unlock
方法的注释会验证此行为。
/**
* 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
)?答案 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中找不到一个。
为什么呢?可能是因为其他人怀疑锁定的效用(和安全性)。